从C#代码调用SQL Server存储过程时出错

本文关键字:存储过程 出错 Server SQL 代码 调用 | 更新日期: 2023-09-27 18:29:38

我有一个存储过程来在SQL Server数据库中创建表。我需要从C#调用这个存储过程。我得到一个异常

@TABLENAME 附近语法不正确

我该如何解决这个问题?我有一个xml文件中的表名和列列表。

存储过程:

CREATE PROCEDURE PROC_CREATE_SFCOM_TABLE2
    @TABLENAME  VARCHAR(4000) ,
    @COLUMNLIST VARCHAR(4000) ,
    @ERRORMSG   VARCHAR(4000) OUTPUT 
AS 
BEGIN
    SET NOCOUNT ON   
        DECLARE @EXEC_IMMEDIATE_VAR VARCHAR (4000)
        SELECT @EXEC_IMMEDIATE_VAR  = 'CREATE TABLE @TABLENAME@COLUMNLIST ' 
        EXECUTE (@EXEC_IMMEDIATE_VAR)
END
GO

C#代码:

using (SqlConnection conn = new SqlConnection(connstring)
{
    using (SqlCommand cmd = new SqlCommand("dbo.PROC_CREATE_SFCOM_TABLE2",conn))
    {
        cmd.CommandType = CommandType.StoredProcedure;
        createScript = "("+columnScript+")";
        if (tableTableSpace != null)
        {
           if (tableTableSpace != "" || tableTableSpace != string.Empty)
           {
               createScript += "TABLESPACE " + tableTableSpace;
           }
        }
        SqlParameter parameter = new SqlParameter("@TableName",SqlDbType.NVarChar);
        parameter.Direction = ParameterDirection.Input;
        parameter.Value = tableName;
        cmd.Parameters.Add(parameter);
        SqlParameter parameter2 = new SqlParameter("@COLUMNLIST",SqlDbType.NVarChar);                        
        parameter2.Direction = ParameterDirection.Input;
        parameter2.Value = createScript;
        cmd.Parameters.Add(parameter2);
        SqlParameter parameter3 = new SqlParameter("@ErrorMsg", SqlDbType.NVarChar);
        parameter3.Direction = ParameterDirection.Output;
        parameter3.Size = 4000;
        cmd.Parameters.Add(parameter3);
        conn.Open();
        cmd.ExecuteNonQuery();
        string errorMsg = parameter3.Value.ToString();
        if (errorMsg != string.Empty)
           LogInfo("Error: " + errorMsg);

从C#代码调用SQL Server存储过程时出错

您不能参数化表或列名。您只能参数化您的值。唯一的方法是执行动态sql。

但是,如果您想创建一个表动态,那么您应该对此进行非常有力的验证。例如,创建一个白名单。

在此之前,请阅读:动态SQL 的诅咒和祝福

您没有正确创建动态SQL字符串。将其更改为。。。

CREATE PROCEDURE PROC_CREATE_SFCOM_TABLE2
    @TABLENAME  VARCHAR(4000) ,
    @COLUMNLIST VARCHAR(4000) ,
    @ERRORMSG   VARCHAR(4000) OUTPUT 
AS 
BEGIN
    SET NOCOUNT ON   
        DECLARE @EXEC_IMMEDIATE_VAR VARCHAR (4000)
        SELECT @EXEC_IMMEDIATE_VAR  = 'CREATE TABLE [' + @TABLENAME + '] ' + @COLUMNLIST
        EXECUTE (@EXEC_IMMEDIATE_VAR)
END
GO

但是,请注意,这是一件非常危险的事情。@COLUMNLIST可能包含任何内容,包括其他SQL命令,这些命令可能用于SQL注入攻击