C# 尝试在C中传递2个参数时,SQL Server存储过程或函数指定的参数太多#

C# 尝试在C中传递2个参数时,SQL Server存储过程或函数指定的参数太多#,c#,sql-server,stored-procedures,C#,Sql Server,Stored Procedures,我正在尝试执行一个名为getLastFeatureUpdate的存储过程 我将在下面一步一步地解释这个问题: 我在SQL中创建了如下表: CREATE TABLE testTable ( DayTime INT NOT NULL, /*yyddhhmm, 1010102345*/ FeatureNbr SMALLINT NOT NULL, Val FLOAT(53) NOT NULL ); 我现在创建了一个名为getLastFeatu

我正在尝试执行一个名为
getLastFeatureUpdate
的存储过程

我将在下面一步一步地解释这个问题:

我在SQL中创建了如下表:

CREATE TABLE testTable
(
      DayTime INT     NOT NULL, /*yyddhhmm, 1010102345*/
      FeatureNbr      SMALLINT  NOT NULL,
      Val FLOAT(53)   NOT NULL
);
我现在创建了一个名为
getLastFeatureUpdate
的存储过程。这里需要注意的是,我使用了两个参数
@maxDateTime
@tableName
,因为它们每次都不同。因此,我将在最后的C代码中传入这两个参数

存储过程(如果我从过程和C#代码中删除
@tableName text
,那么代码确实可以使用)

C#代码:


无法在SQL Server中参数化表名,因此:该SQL无效,并且
CREATE PROC
实际上没有运行。旧程序的内容是什么:只有您知道,但是:它不是显示的代码。它可能是您在开发过程中的某个时候使用的虚拟版本。尝试键入:

exec sp_helptext getLastFeatureUpdate;
具体来说,服务器应该告诉您:

Msg 1087, Level 16, State 1, Procedure getLastFeatureUpdate, Line 12 [Batch Start Line 0]
Must declare the table variable "@tableName".
Msg 1087, Level 16, State 1, Procedure getLastFeatureUpdate, Line 19 [Batch Start Line 0]
Must declare the table variable "@tableName".

不要使用文本数据类型,因为它的折旧已超过SQL Server 2005。你应该用varchar或nvarchar来代替。诺兰,那太好了。很好,你提到了。我会改变的。不要将日期或日期时间存储为数字。这条路只会给你带来未来的问题和更多的工作——更多的工作。如果你做了一点实验,你就会发现为什么你不能用INT来在你的评论中存储样本值。而且你关于Day列的评论是不正确的-它是YYYYMMDDHHMM(或者可能是YYYYDDMM?因为没有任何东西可以将值约束到有效的日期和时间,所以不能真正说。或者,关于
int
,您是对的,它不能接受
yyymmddhhmm
。最初我的测试代码中只有
yymddhhmm
。我将改变我的职位。我必须记住这一点,以便datetime数字以后不再使用int。我理解,但我想知道如果不能将其作为参数传递,存储过程如何能够知道应该在哪个表上执行此命令?例如,我可以有100个不同的表。这里有一个初学者问题:我不确定什么时候应该在VisualStudio中执行该命令<代码>exec sp_helptext getLastFeatureUpdate@coding坏消息:“这是不可能的”-您不应该拥有由表参数化的存储过程。无论您以何种方式对其进行切片,最终都会在这里连接字符串,这只是在乞求SQL注入问题。我强烈建议您重新考虑您的方法。@为执行SQL编写代码时,您可能希望使用SSMS,而不是可视化的Studio@coding问题,;为什么这里需要存储过程?但是:在运行时创建大量表通常是设计中出现严重错误的标志;有时它是有效的,但大多数应用程序都不是这样运行的;最终,您将不得不求助于在这种模型下在运行时编写SQL。这可以在SQL或C#(或任何其他语言)中完成,但如果您没有完全正确地使用SQL,则会带来SQL注入的固有风险
cmd.Parameters.Add(new SqlParameter("@maxDateTime", 10102248));
cmd.Parameters.Add(new SqlParameter("@tableName", "testTable")); //If not using this parameter, the code will work
void getLastFeatureUpdate()
{
        using (SqlConnection conn = new SqlConnection(GetConnectionString()))
        {
            conn.Open();

            // 1. create a command object identifying the stored procedure
            SqlCommand cmd = new SqlCommand("getLastFeatureUpdate", conn);

            // 2. set the command object so it knows to execute a stored procedure
            cmd.CommandType = CommandType.StoredProcedure;

            // 3. add parameter to command, which will be passed to the stored procedure
            cmd.Parameters.Add(new SqlParameter("@maxDateTime", 10102248));
            cmd.Parameters.Add(new SqlParameter("@tableName", "testTable")); //If not using this parameter, the code will work

            // execute the command
            using (SqlDataReader rdr = cmd.ExecuteReader())
            {
                // iterate through results, printing each to console
                while (rdr.Read())
                {
                    int v1 = (int)rdr["DayTime"];
                    int v2 = (Int16)rdr["FeatureNbr"];
                    double v3 = (double)rdr["Val"];

                    MessageBox.Show(v1 + "," + v2 + "," + v3);
                }
            }
        }
}

static private string GetConnectionString()
{
    return "Data Source=(LocalDB)\\MSSQLLocalDB;AttachDbFilename=C:\\Users\\andre\\source\\repos\\TestDatabaseCreation\\DatabaseTest.mdf;Integrated Security=True;Connect Timeout=30";
}
Msg 1087, Level 16, State 1, Procedure getLastFeatureUpdate, Line 12 [Batch Start Line 0]
Must declare the table variable "@tableName".
Msg 1087, Level 16, State 1, Procedure getLastFeatureUpdate, Line 19 [Batch Start Line 0]
Must declare the table variable "@tableName".