2013-02-13 45 views
0

我有一個表的列表,其中一些列有Employee_ID。至少有一個表缺少至少一個Employee_ID。我想從其他表中找到Employee_ID的缺失。帶表變量的TSQL範圍

我運行以下命令,但在@temp_employees上出現「必須聲明標量變量」錯誤。我相信範圍是正確的。

如何在TSQL內部使用表變量@temp_employees,同時保持其作用域,以便在整個循環中使用它?

注意:這些年來軟件有很多版本和許多表格結構的變化。我不想爲每個表結構更改編寫特定於版本的腳本,因爲缺少的Employee_ID始終是軟件中錯誤的來源。

/*************************************************************** 
* Find missing employee id's regardless of software version * 
***************************************************************/ 
USE [database name] 

DECLARE @i AS INT, 
     @iMAX AS INT, 
     @SQL AS nvarchar(MAX), 
     @table AS nvarchar(MAX) 

DECLARE @temp_tables TABLE (
    id int identity(1,1), 
    table_name nvarchar(MAX) NULL 
)  

DECLARE @temp_employees TABLE (
    id int identity(1,1), 
    employee_id int NOT NULL, 
    table_name nvarchar(255) NULL 
) 

INSERT @temp_tables (table_name) SELECT t.name FROM sys.tables t 
    INNER JOIN sys.columns c ON t.object_id = c.object_id WHERE c.name = 'employee_id' 
SELECT * FROM @temp_tables 

SELECT @i = MIN(id) FROM @temp_tables 
SELECT @iMAX = MAX(id) FROM @temp_tables 

WHILE (@i < @iMAX) 
BEGIN 
    SELECT @table = table_name FROM @temp_tables WHERE id = @i 

    SELECT @SQL = N'INSERT ' + @temp_employees + ' (employee_id, table_name) SELECT employee_id, ''' + @table + ''' FROM ' + @table + ' WHERE employee_id NOT IN (SELECT employee_id FROM ' + @temp_employees + ')' 
    EXEC sp_executeSql @SQL 

SET @i = @i + 1 
END 

SELECT * FROM @temp_employees 

回答

1

當您使用sp_executesql時,它會在其他範圍內執行腳本。我有一個簡短的博客文章,涉及here

1

...SELECT @SQL = N'INSERT ' + @temp_employees + '...

你nvarchar的混合與表變量。這就是爲什麼你得到這個錯誤「必須聲明變量」

我認爲你應該創建一個持久表

... 
DECLARE temp_employees TABLE (
    id int identity(1,1), 
    employee_id int NOT NULL, 
    table_name nvarchar(255) NULL 
) 
... 
    SELECT @SQL = N'INSERT temp_employees (employee_id, table_name) 
... 
+0

我在添加一個臨時表中的位置已經不像我將處理對於〜100個表格,其範圍問題相同。 是否有另一種解決方法? 編輯:「是的」有「有」 – 2013-02-15 18:02:53

+0

那麼這是對你的錯誤的解釋。您可以使用臨時表而不是表變量。 '聲明#temp_employees ... SELECT @SQL = N'INSERT #temp_employees ...',您將能夠訪問代碼中的#temp_employees以及您的動態SQL。 – Daniel 2013-02-15 19:49:46