将sql脚本转换为存储过程

时间:2014-09-22 06:27:09

标签: sql sql-server stored-procedures

我有这张桌子:

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

我做错了什么?我需要做什么才能将上面的脚本转换为存储过程? 提前谢谢。

2 个答案:

答案 0 :(得分: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..'+@LclTable)

select * from #col_names

SET @sqlstr = N'DELETE C
                FROM ( SELECT *  from '+@inputtable +'
                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

将脚本转换为sp

时存在一些问题
  • 您尚未执行@sqlstr
  • 未正确转义@sqlstr
  • 中的所有字符
  • 在SET操作之前使用的@sql变量

答案 1 :(得分:0)

首先尝试更改

DROP TABLE @LclTable

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