首页 > 解决方案 > 创建 SQL 表,使用 C# 将 tableName 作为参数传递会出错

问题描述

我正在尝试创建一个createNewTable创建新表的存储过程。

如果我在没有 C# 的情况下按原样执行该过程,则它可以在我硬编码表的名称testTable5(被注释的代码)的地方工作。

我现在要做的是使用 C# 执行这个存储过程。我在这里还想做的是将表的名称作为参数传递。所以我尝试传递名称:testTable5.

但是当我执行 C# 代码时出现此错误:

System.Data.SqlClient.SqlException:''testTable5' 附近的语法不正确

我想知道我在这段代码中做错了什么?

存储过程(注释掉的代码是硬编码的原始代码)

--CREATE PROCEDURE createNewTable
--AS
--CREATE TABLE testTable5
--(
--    [DateTime]    SMALLDATETIME  NOT NULL,
--    [FeatureNbr]  SMALLINT         NOT NULL,
--    [Value]       FLOAT (53)       NULL,
--    [Bool]        BIT              NULL,
--  CONSTRAINT UC_testTable5 UNIQUE (DateTime),
--  CONSTRAINT PK_testTable5 PRIMARY KEY (FeatureNbr, DateTime)
--);


CREATE PROCEDURE createNewTable
    @tableName nvarchar(max)
AS
BEGIN
    DECLARE @FullQuery nvarchar(1000)
    SET @FullQuery = N'CREATE TABLE ' + QUOTENAME(@tableName) + ' ([DateTime] SMALLDATETIME NOT NULL, [FeatureNbr] SMALLINT NOT NULL, [Value] FLOAT (53) NULL, [Bool] BIT NULL, 
                     CONSTRAINT UC_' + QUOTENAME(@tableName) + ' UNIQUE (DateTime), 
                     CONSTRAINT PK_' + QUOTENAME(@tableName) + ' PRIMARY KEY (FeatureNbr, DateTime));'

    EXECUTE sp_executesql @FullQuery;
END

C# 代码(执行此存储过程)

void createNewTable()
{
    using (SqlConnection conn = new SqlConnection(GetConnectionString()))
    {
        SqlCommand cmd = new SqlCommand("createNewTable", conn); //1. create a command object identifying the stored procedure
        cmd.CommandType = CommandType.StoredProcedure; //2. set the command object so it knows to execute a stored procedure
        cmd.Parameters.Add(new SqlParameter("@tableName", "testTable5"));

        int i = cmd.ExecuteNonQuery();
    }
}

static private string GetConnectionString()
{
    return "Data Source=(LocalDB)\\MSSQLLocalDB;AttachDbFilename=C:\\Users\\andre\\source\\repos\\TestDatabaseCreation\\DatabaseTest.mdf;Integrated Security=True;Connect Timeout=30";
}

标签: c#sql-serverstored-procedures

解决方案


UC_' + QUOTENAME(@tableName)会创建类似UC_[TableName]. 对象名称不能包含特殊字符,除非已确定分隔符(因此,如果您真的想要一个具有该名称的唯一约束,您可以将其定义为[UC_[tablename]]]; 但我强烈建议不要使用任何这样的名称)。

您需要引用整个值:QUOTENAME(CONCAT(N'UC_',@tablename)). 那将产生价值[UC_tablename]

此外,参数@tableName不应为. 对象名称不能超过 128 个字符,并且对象名称有特定的数据类型,它是 的同义词。nvarchar(MAX)sysnamenvarchar(128) NOT NULL


推荐阅读