创建 SQL table,使用 C# 传递 tableName 作为参数会出错

Creating a SQL table, passing a tableName as parameter using C# gives an error

我正在尝试创建一个存储过程 createNewTable,它会创建一个新的 table。

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

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

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

System.Data.SqlClient.SqlException: 'Incorrect syntax near '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";
}

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

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

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

的同义词