我試圖將一些非常往返繁重的C#代碼轉換爲實現了表格變種的一個SQL腳本塊。這是非生產代碼,基本上從表中清除測試數據,並將它們作爲測試套件的一部分重新加入。選擇在變量中提供列名稱的列的最大值
當我嘗試選擇列名稱保存在變量(下面的腳本中的'@IdentityColumnName')中的標識列的最大值時,會出現問題。
當此腳本執行時,我得到一個包含MAX(@IdentityColumnName)行了以下錯誤...
錯誤轉換數據類型爲varchar爲bigint。
......我認爲這是因爲SQL假設我要求它爲變量的MAX,而不是將它視爲列的名稱。
-- Assume that some (or all) existing values have been removed from the table prior to this...
IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '__Foo' AND COLUMNPROPERTY(OBJECT_ID(TABLE_NAME), COLUMN_NAME, 'IsIdentity') = 1)
BEGIN
DECLARE @IdentityColumnName AS VARCHAR(MAX)
DECLARE @IdentityColumnValue AS BIGINT
SELECT TOP 1 @IdentityColumnName = [COLUMN_NAME] FROM [INFORMATION_SCHEMA].[COLUMNS] WHERE [TABLE_NAME] = '__Foo'
SELECT @IdentityColumnValue = ISNULL(MAX(@IdentityColumnName), 0) FROM [__Foo]
-- Reseed the table with either 0 (if it's empty) or the maximum value already in the table
DBCC CHECKIDENT ('__Foo', RESEED, @IdentityColumnValue)
END
有誰知道這是否可能有SQL將該變量當作一個列的名稱,所以我的查詢是否行得通呢?我試過建立一個字符串並用EXEC執行它,但這導致了捕獲EXEC結果的困難,我想確認沒有更簡單的方法來實現這一點。
- 如果這樣做會產生影響,代碼將需要對SQL Server 2008 R2起作用。
- 這只是非生產測試的東西;它不必遵守任何最佳實踐。
- 通常會有一個DELETE FROM和可選的WHERE xyz在種子之前立即執行。有時桌子最後是空的,有時候它還有幾排。
如果您希望列是動態的,則需要使用動態SQL。 –
'\t SET @SQL = N' \t \t DECLARE @IdentityColumnValue AS BIGINT; \t \t SELECT @IdentityColumnValue = ISNULL(MAX( '+ QUOTENAME(@IdentityColumnName)+ N '),0)FROM [__Foo] \t \t DBCC CHECKIDENT(N' '__富'',RESEED,@IdentityColumnValue);'; \t EXEC(@SQL);' –