Как использовать имя базы данных в процедуре

#sql-server #tsql #sql-server-2008 #stored-procedures

#sql-сервер #tsql #sql-server-2008 #хранимые процедуры

Вопрос:

Я создал процедуру, которая будет выводить INSERT скрипт для заданного имени таблицы. И в процедуре я использую этот код:

 DECLARE @owner VARCHAR(20) ,
    @Database VARCHAR(50)

SELECT  @owner = 'dbo' ,
        @Database = 'Asmin'

 SELECT   sc.name
   FROM     sysobjects so
            INNER JOIN syscolumns sc ON so.id = sc.id
            INNER JOIN systypes st ON sc.xtype = st.xusertype
   WHERE    so.Name = 'Acisd'
  

Но проблема, которую я вижу, заключается в том, что процедура находится в базе данных коллекции, а таблица Acisd находится в другой базе данных. Поэтому он ничего не возвращает мне, когда я выполняю процедуру.

Как это исправить?

Комментарии:

1. Укажите имена таблиц / процедур / etc с базой данных и схемой, разделенные точками. db_name..object_name , или db_name.schema_name.object_name (пример: db_name.dbo.object_name ).

Ответ №1:

Не совсем уверен, что вы здесь делаете, но вы могли бы указать весь этот оператор на другую базу данных, полностью указав ссылки на таблицы.

 SELECT   sc.name
   FROM     OtherDatabase.dbo.sysobjects so
            INNER JOIN OtherDatabase.dbo.syscolumns sc ON so.id = sc.id
            INNER JOIN OtherDatabase.dbo.systypes st ON sc.xtype = st.xusertype
   WHERE    so.Name = 'Acisd'
  

Комментарии:

1. и если вы используете SQL Server 2005 или новее, вы должны использовать sys.columns вместо syscolumns (и так далее, для других представлений системного каталога тоже)

2. @Joe Stefanelli Пожалуйста, посмотрите мой обновленный вопрос. Я использую две переменные для имени схемы и базы данных, так как же мне их использовать?

Ответ №2:

Чтобы сделать это внутри хранимой процедуры, вам необходимо использовать динамический SQL. Например:

 declare @sql nvarchar(max);
set @sql = N'SELECT   sc.name
      FROM '   quotename(@dbanme)   N'.sys.objects so
      INNER JOIN '   quotename(@dbname)   N'sys.columns sc ON so.id = sc.id
      INNER JOIN '   quotename(@dbname)   N'sys.types st ON sc.xtype = st.xusertype
      WHERE so.Name = @objectName';
exec sp_executesql @sql, N'@objectName sysname', @objectName;
  

Комментарии:

1. Я получаю следующую ошибку Msg 214, уровень 16, состояние 3, процедура sp_executesql, строка 1 Процедура ожидает параметр «@parameters» типа «ntext / nchar / nvarchar».

Ответ №3:

В sybase есть функция db_name() для ktakeout текущей базы данных… не уверен в sqlserver

Ответ №4:

В MySQL есть предложение «Use», которое может предшествовать любому оператору select. Я полагаю, что это также имеет место в SQL — Server.

Комментарии:

1. Я знаю, но вы не можете использовать предложение ‘Use’ внутри процедуры

Ответ №5:

Как сказал previus, самый простой способ сделать это — просто начать с

ИСПОЛЬЗУЙТЕ [otherDatabasename]

Вперед

ОБЪЯВИТЬ @owner VARCHAR(20) , @Database VARCHAR(50)

ВЫБЕРИТЕ @owner = ‘dbo’, @Database = ‘Asmin’

ВЫБЕРИТЕ sc.name ИЗ sysobjects so ВНУТРЕННЕЕ ОБЪЕДИНЕНИЕ syscolumns sc НА so.id = sc.id ВНУТРЕННЕЕ ОБЪЕДИНЕНИЕ системных типов st В sc.xtype = st.xusertype, ГДЕ so.Name = ‘Acisd’

Комментарии:

1. вы не можете использовать предложение ‘Use’ внутри процедуры