2017-04-09 18 views
1
DECLARE @counter INT = 1 

WHILE ((SELECT count(*) from ##tmp_tname_pkey_map) >= @counter-1) 
BEGIN 

DECLARE @table varchar(250); 
DECLARE @primarykey varchar(250); 
    SELECT @table = TABLE_NAME from ##tmp_tname_pkey_map where INDEX_ID = @counter; 
    SELECT @primarykey = PRIMARY_KEY_COLUMN from ##tmp_tname_pkey_map where INDEX_ID = @counter; 

      DECLARE @query nvarchar(max); 
      DECLARE @maxVal BIGINT; 
      SET @query = 'SELECT @maxVal = max(' + @primarykey + ') from ' + @table; 

      EXEC sp_executesql @query, N'@maxVal INT out', @maxVal out 

上面的代碼是,我使用來獲取所有表和它們的主鍵(除了一個表大多整數)的列表,並獲得它們的最大的存儲過程的一部分值。執行SQL與輸出參數(與IF條件)

這適用於包含變量@primarykey的INT值的表。

我的問題是如果有一種方法可以在執行查詢之前檢查INT類型的查詢之前/之前包含條件的錯誤。

+0

當你填入您的臨時表,列出指標,也可能設置類型,然後有兩個可能的語句之一,您對整數做,一個用於任何其他類型。 – TZHX

+0

@SqlZim - 上面的代碼是存儲過程的一部分,它爲架構中的每個表創建一個包含表名,主鍵,主鍵的最大值的表。當主鍵不是int/bigint類型時,我查詢max(主鍵)時失敗 – prax

回答

0

我很想知道你會用這種東西,這個操作提供了什麼價值?


一般注意事項:

  • 聲明變量的循環之外,並重新設置你的循環中。
  • 使用sysname可獲得系統對象的名稱,以便在腳本中實現向前(和向後)兼容性。
  • 您可以使用一個select來設置多個變量。
  • 使用quotename()圍繞可能具有空格或其他字符的對象名稱,這些對象名稱需要用動態sql的方括號包裝。
  • 您可能可以使用本地臨時表而不是全局臨時表。
  • 您可以爲datatype添加一列,並將其包含在##tmp_tname_pkey_map的生成中以簡化此過程。
declare @table sysname, @primarykey sysname, @primarykey_datatype sysname; 
declare @query nvarchar(max); 
declare @maxVal bigint; 

declare @count int = (select count(*) from ##tmp_tname_pkey_map); 
declare @i int = 1; 

while (@i <= @count) 
begin; 
    /* reset variables */ 
    select 
    @table = null 
    , @primarykey = null 
    , @primarykey_datatype = null 
    , @query = null 
    , @maxVal = null; 

    /* get variable values from temp table */ 
    select 
     @table = table_name 
    , @primarykey = primary_key_column 
    , @query = 'select @maxVal = max(' + quotename(primary_key_column) 
      + ') from ' + quotename(table_name)+';'; 
    from ##tmp_tname_pkey_map 
    where index_id = @i; 

    /* using system catalog views to get the datatype of a column */ 
    select @primarykey_datatype = y.name 
    from sys.tables t 
    inner join sys.columns c 
     on t.object_id = c.object_id 
    inner join sys.types y 
     on c.user_type_id = y.user_type_id 
    where t.name = @table 
     and c.name = @primarykey; 

    /* check primary key data type, set @query null if not integer based */ 
    if @primarykey_datatype not in ('tinyint', 'smallint', 'int', 'bigint') 
    begin; 
    set @query = null; 
    print @table +' primary key '[email protected]+' datatype is: '[email protected]_datatype; 
    end; 

    /* execute @query if it is not null */ 
    if @query is not null 
    begin; 
    exec sp_executesql @query, N'@maxVal int output', @maxVal out; 
    end; 

    /* increment loop counter @i */ 
    set @i = @i + 1; 
end; 
+0

上述代碼是存儲過程的一部分,它創建一個包含每個表的PrimaryKey的Tablename,PrimaryKey,Max值的表在架構中。它在主鍵不是int/bigint類型時查詢max(主鍵)時失敗。 感謝您上面的代碼,我現在可以獲取列的數據類型。欣賞它。 – prax

+0

真棒,這個作品完美.. :-) – prax

0

我不知道我完全理解你的代碼,但它看起來像你正在使用全局臨時表。也許你應該先使用ISNUMERIC函數過濾掉記錄。