在SQL Server

时间:2016-07-13 20:10:34

标签: sql-server tsql

当我尝试使用exec命令为表名调用参数var时,显然存在语法错误。

这是我的代码:

ALTER PROCEDURE [dbo].[createTable] 
    @tblName varchar(30), 
    @tblSTDColumns int = 0,
    @dupExistTblName varchar(60) = ''
AS
BEGIN
    SET NOCOUNT ON;

    SET @dupExistTblName = @tblName + '_COPY'   

    IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES 
               WHERE table_name LIKE @tblName)
    (       
        EXEC('SELECT * INTO [' + @dupExistTblName + '] FROM [' + @tblName + '] WHERE 1=2')      
    )

    EXEC('DROP TABLE ['+ @tblName + ']')

    EXEC('SELECT * INTO [' + @tblName + '] FROM [' + @dupExistTblName] + ' WHERE 1=2')
END

EXEC('SELECT * INTO [' + @dupExistTblName + '] FROM [' + @tblName + '] WHERE 1=2')生成语法错误

3 个答案:

答案 0 :(得分:0)

你错过了一些东西,并错放了其他东西。

2.example.com

答案 1 :(得分:0)

A) MSDN在每个相关网页上都说明了这一点:

  

验证所有用户输入。不要在您之前连接用户输入   验证它。永远不要执行由未经验证的用户构造的命令   输入

IF中的

B) TSQL语句仅适用于SQL中的下一个查询/命令行。使用BEGIN END是确保正确执行的好方法。当然,你的风格是明确的。

C)CREATE / ALTERAS BEGIN之间声明变量意味着您希望这些变量具有用户输入。 (@dupExistTblName)会立即被替换吗?

以下是一种方法,其中包含一种安全风格,额外加上RAISERROR以防止致命错误并提供反馈。

ALTER PROCEDURE [dbo].[createTable] 
    @tblName varchar(30)
--    @tblSTDColumns int = 0
AS
BEGIN   
    SET NOCOUNT ON;
    DECLARE @string NVARCHAR(255);
    IF OBJECT_ID(@tblName) IS NOT NULL
        BEGIN
        DECLARE @dupExistTblName varchar(60);
        SET @dupExistTblName = @tblName + '_COPY';
            BEGIN
            SET @string = N'SELECT * INTO ' + QUOTENAME(@dupExistTblName) + ' FROM ' + QUOTENAME(@tblName) + ' WHERE 1=2';
            --SELECT @string
            EXEC (@string);
            END
        END
    ELSE
    -- no need for a fatal error from trying to input a bad table name.
    RAISERROR('Unknown Error. You Entered: %s. Check syntax.'
                , 10
                , 1
                , @tblName)
END

EXEC dbo.createTable @tblName = 'MyNAMEST'
  

未知错误。你输入了:MyNAMEST。检查语法。

为了进一步增加保护,MSDN推广使用sp_executesql,允许自己缓存SQL语句。有许多不同的编写方式,例如:

EXEC sp_executesql N'SELECT * INTO QUOTENAME(@TblcopyName) 
                     FROM QUOTENAME(@tbleName) WHERE 1 = 2'
                   , N'@TblcopyName NVARCHAR(50), @tbleName NVARCHAR(50)'
                   , @TblcopyName = @dupExistTblName
                   , @tblName = @tblName

答案 2 :(得分:0)

这就是我最终的结果!谢谢大家!

void graph::addEdge(***int*** n, pii m)
{
    adj[n].push_back(m);        //Error Line
}