Получение метаданных из другой базы данных в sproc в SQL Server? - PullRequest
1 голос
/ 04 июля 2010

Как мне создать хранимую процедуру, которая существует в одной базе данных, но запускает приведенный ниже код для другой (любой) базы данных?

SET @sql1 = N'INSERT INTO #Tables SELECT'
          + N' t.TABLE_NAME as TableName'
          + N',t.TABLE_SCHEMA as SchemaName'
          + N',(SELECT OBJECTPROPERTY(OBJECT_ID(t.TABLE_SCHEMA + ''.'' + t.TABLE_NAME),''TableHasIdentity'')) '
          + N'FROM ' + QUOTENAME(@TargetDBName) 
          + N'.INFORMATION_SCHEMA.TABLES t'
IF @Verbose = 1
    PRINT @sql1
EXEC(@sql1)

Я успешно получаю TABLE_NAME и SCHEMA_NAME, но основная проблема заключается в том, что OBJECTPROPERTY() выполняется в контексте базы данных хранимой процедуры, а не в контексте @TargetDBName.Итак, OBJECTPROPERTY () всегда будет возвращать ноль, если @TargetDBName не совпадает с базой данных, в которой находится sproc.

В настоящее время я использую SQL Server 2008.

Ответы [ 3 ]

1 голос
/ 04 июля 2010

Запросите sys-представления напрямую, как это

SELECT  Tbl.name AS TableName, sch.name AS SchemaName,
HasIdentity = CASE WHEN EXISTS (SELECT * FROM your_target_db.sys.columns AS cols WHERE Tbl.object_id = cols.object_id and is_identity = 1) THEN 1 ELSE 0 END
 FROM your_target_db.sys.tables AS Tbl INNER JOIN  your_target_db.sys.schemas AS SCH ON Tbl.schema_id = Sch.schema_id
0 голосов
/ 05 июля 2010

Рассматривали ли вы использование IDENT_SEED в динамическом запросе?

Это вернет начальное значение столбца идентификации таблицы или NULL, если он не существует.

Пример:

USE master
GO

CREATE DATABASE Test
GO

USE Test
GO

CREATE TABLE Test1 (ColA INT IDENTITY(100,1))
CREATE TABLE Test2 (ColA INT)
GO

USE master
GO

DECLARE @TargetDBName NVARCHAR(MAX), @sql1 NVARCHAR(MAX)

SET @TargetDBName = 'Test'

SET @sql1 = N'SELECT' 
          + N' t.TABLE_NAME as TableName' 
          + N',t.TABLE_SCHEMA as SchemaName' 
          + N',(SELECT CASE WHEN IDENT_SEED(''' 
            + QUOTENAME(@TargetDBName) + '.'' 
            + t.TABLE_SCHEMA + ''.'' 
            + t.TABLE_NAME) IS NOT NULL THEN 1 ELSE 0 END) as HasIdentity ' 
          + N'FROM ' + QUOTENAME(@TargetDBName)  
          + N'.INFORMATION_SCHEMA.TABLES t'  

EXEC(@sql1) 
GO

DROP DATABASE Test
GO

Результаты:

TableName  SchemaName  HasIdentity
---------- ----------- -----------
Test1      dbo         1
Test2      dbo         0

Одно предостережение, которое вам может потребоваться:

Возвращает NULL при ошибке или если вызывающаянет разрешения на просмотр объекта.

0 голосов
/ 04 июля 2010

Не могли бы вы вместо этого использовать OPENQUERY ( см. Здесь )?

...