2014-09-22 92 views
0

我有這個表:轉換SQL腳本存儲過程

CREATE TABLE #tmp (a nvarchar(max), b nvarchar(10), c nvarchar(100), d nvarchar(1000), e datetime, f int) 
INSERT #tmp VALUES ('1', null, '2', null, GETDATE(), null) 

和丟棄空列這個SQL腳本:

SELECT * 
FROM #tmp 

SELECT name, CAST(0 AS BIT) checked 
INTO #col_names 
FROM tempdb.sys.columns 
WHERE object_id = OBJECT_ID('tempdb..#tmp') 

DELETE C 
FROM ( SELECT * 
      FROM #tmp 
      FOR XML PATH(''), TYPE) AS T(XMLCol) 
     CROSS APPLY T.XMLCol.nodes('*') AS n(Col) 
     INNER JOIN #col_names C 
      ON c.name = Col.value('local-name(.)', 'varchar(max)') 

DECLARE @sql NVARCHAR(MAX) 

SELECT @sql = COALESCE(@sql + ', ' + QUOTENAME(name), QUOTENAME(name)) 
FROM #col_names 

SET  @sql = 'ALTER TABLE #tmp DROP COLUMN ' + @sql 

PRINT @sql 
EXEC (@sql) 

SELECT * 
FROM #tmp 

DROP TABLE #tmp 
DROP TABLE #col_names 

這完全正常工作。現在我試圖將其轉換爲存儲過程,並且出現錯誤SELECT語法不正確?

CREATE PROCEDURE SP_DROP_NULL 
@inputtable AS NVARCHAR(50) 

AS 
BEGIN 

    DECLARE @sql NVARCHAR(MAX) = '' 
    DECLARE @sqlstr NVARCHAR(MAX) = '' 
    DECLARE @LclTable NVARCHAR(50) 

    SET @LclTable = @inputtable 
    SET @sql = 'SELECT * FROM ' + @LclTable 

    SELECT name, CAST(0 AS BIT) checked 
    INTO #col_names 
    FROM tempdb.sys.columns 
    WHERE object_id = OBJECT_ID(@LclTable) 

    SET @sqlstr = N'DELETE C 
        FROM (SELECT * 
        FOR XML PATH(''), TYPE) AS T(XMLCol) 
       CROSS APPLY T.XMLCol.nodes(''*'') AS n(Col) 
       INNER JOIN #col_names C 
        ON c.name = Col.value(''local-name(.)'',''VARCHAR(MAX)'')' 


    SELECT @sql = COALESCE(@sql + ', ' + QUOTENAME(name), QUOTENAME(name)) 
    FROM #col_names 

    SET  @sql = 'ALTER TABLE '+ @LclTable + ' DROP COLUMN ' + @sql 

    PRINT '@sql is: ' + @sql 
    EXEC (@sql) 

    SET @sql = 'SELECT * FROM ' + @LclTable 

    DROP TABLE @LclTable 
    DROP TABLE #col_names 

END 

我做錯了什麼?我需要做什麼才能將上述腳本轉換爲存儲過程? 在此先感謝。

+1

請張貼完整的錯誤消息。同時雙擊錯誤消息並指出失敗的原因。當我跑這個時,我實際上得到了'Msg 102,Level 15,State 1,Procedure SP_DROP_NULL,Line 37'@ LclTable'附近的語法不正確,這是合理的,因爲DROP TABLE @ LclTable不是有效的SQL。如果您將它與您的原始腳本進行比較,則它與其他許多事情不同。 – 2014-09-22 07:02:24

+0

以下是完整的錯誤消息:(0行受影響) 消息263級別16狀態1行1 必須指定要從中選擇的表。 @sql is:ALTER TABLE #tmp DROP COLUMN SELECT * FROM #tmp Msg 156,Level 15,State 1,Line 1 關鍵字'SELECT'附近的語法不正確。 – Tempo 2014-09-22 07:05:16

+0

好的,我們在這裏有一些混亂。現在這個消息是在我的答案中指出的變化之後?看起來你把我建議的改變應用到了錯誤的地方。這會變得非常混亂。 – 2014-09-22 07:25:15

回答

0

更新的存儲過程的代碼

Create PROCEDURE SP_DROP_NULL 
@inputtable AS NVARCHAR(50) 

AS 
BEGIN 

DECLARE @sql NVARCHAR(MAX) 
DECLARE @sqlstr NVARCHAR(MAX) = '' 
DECLARE @LclTable NVARCHAR(50) 
DECLARE @Dropsql NVARCHAR(MAX) = '' 
SET @LclTable = @inputtable 

exec ('SELECT * FROM ' + @LclTable) 


SELECT name, CAST(0 AS BIT) checked 
INTO #col_names 
FROM tempdb.sys.columns 
WHERE object_id = OBJECT_ID('tempdb..'[email protected]) 

select * from #col_names 

SET @sqlstr = N'DELETE C 
       FROM (SELECT * from '[email protected] +' 
       FOR XML PATH(''''), TYPE) AS T(XMLCol) 
      CROSS APPLY T.XMLCol.nodes(''*'') AS n(Col) 
      INNER JOIN #col_names C 
       ON c.name = Col.value(''local-name(.)'',''VARCHAR(MAX)'')' 


exec (@sqlstr) 

select * from #col_names 
SELECT @sql = COALESCE(@sql + ', ' + QUOTENAME(name), QUOTENAME(name)) 
FROM #col_names 
SET  @sql = 'ALTER TABLE '+ @LclTable + ' DROP COLUMN ' + @sql 
PRINT '@sql is: ' + @sql 
EXEC (@sql) 

SET @sql = 'SELECT * FROM ' + @LclTable 

SET @Dropsql = 'DROP TABLE ' + @LclTable 
EXEC (@Dropsql) 

DROP TABLE #col_names 

END 

有一些問題,同時將你的腳本用上

  • 您還沒有@sqlstr
  • 不正確地轉義所有字符在執行@ sqlstr
  • SET操作之前使用的@sql變量
+0

謝謝,但這不是,請看我對尼克的迴應。 – Tempo 2014-09-22 07:15:35

+0

通過回答詳細資料更新 – NMK 2014-09-22 09:12:19

+0

謝謝Mohank。你的解決方案解決了一些問題,但最後一件事仍然懸而未決。現在,我可以在日誌中看到的錯誤涉及到:SET @ sql ='ALTER TABLE'+ @ LclTable +'DROP COLUMN'+ @ sql PRINT'@ sql is:'+ @ sql .... .................................................. .............. EXEC(@sql)<---它不像這個聲明的某種原因 – Tempo 2014-09-22 09:44:43

0

首先嚐試改變

DROP TABLE @LclTable 

SET @sql = 'DROP TABLE @LclTable' 
EXEC(@sql) 
+0

感謝您的回覆。這些行只是爲了垃圾收集,我評論他們,仍然得到相同的錯誤。該錯誤是涉及這些部分:SELECT姓名,CAST(0 AS BIT)檢查 INTO #col_names FROM tempdb.sys.columns WHERE的object_id = OBJECT_ID(@LclTable) SET @sqlstr = N'DELETEÇ FROM (SELECT * FOR XML PATH(''),TYPE)AS T(XMLCol) CROSS APPLY T.XMLCol.nodes(''*'')AS n(Col) INNER JOIN #col_names C ON c.name = Col.value(''local-name(。)'',''VARCHAR(MAX)'')' – Tempo 2014-09-22 07:12:14

+0

您是否可以更新您的問題以反映此信息 – 2014-09-22 07:16:23

+0

我只是試圖從腳本創建存儲過程。我得到的錯誤來自於這部分腳本:SELECT name,CAST(0 AS BIT)checked INTO #col_names FROM tempdb.sys.columns WHERE object_id = OBJECT_ID(@LclTable)SET @sqlstr = N'DELETE C FROM (SELECT * FOR XML PATH(''),TYPE)AS T(XMLCol)CROSS APPLY T.XMLCol.nodes(''*'')AS n(Col)INNER JOIN #col_names C ON c.name = Col.value ('本地名稱() '', '' VARCHAR(MAX) '')」 – Tempo 2014-09-22 07:24:00