C# MS-SQL存储过程不';不能使用空参数

C# MS-SQL存储过程不';不能使用空参数,c#,sql-server,C#,Sql Server,我有一个输入“姓名”和“电话”的表格 当它们有值时,一切正常:使用存储过程spFoo: String sp = "spFoo 'test name','test phone'"; OdbcCommand command = new OdbcCommand(sp, connection); command.CommandType = System.Data.CommandType.StoredProcedure; connection.Open(); Response.Write(command.

我有一个输入“姓名”和“电话”的表格

当它们有值时,一切正常:使用存储过程spFoo:

String sp = "spFoo 'test name','test phone'";
OdbcCommand command = new OdbcCommand(sp, connection);
command.CommandType = System.Data.CommandType.StoredProcedure;
connection.Open();
Response.Write(command.ExecuteNonQuery().ToString());
  • 申请工作
  • 管理工作室作品
但是当它们没有值时,我在应用程序中得到-1作为响应:

String sp = "spFoo '',''";
  • 在应用程序(-1)中不起作用
  • 管理工作室作品
我希望用户能够在没有任何输入的情况下创建记录

为什么这在ManagementStudio中有效,但在应用程序中却不起作用


更新:我在存储过程中为参数添加了默认值,它不起作用;我给空字符串“NULL”作为代码中的值,仍然没有运气。这是服务器设置还是不允许使用空变量的设置?

从代码调用存储过程时,应使用命令的Parameters属性。试试这个:

String sp = "spFoo";
command.Parameters.Add("@name", "test name");
command.Parameters.Add("@phone", "test phone");

正如JimmyV所说,您应该使用command.Parameters.Add方法来设置参数,在未指定参数值时传入null。要解决有关错误“过程或函数“spFoo”需要参数“@name”(未提供),您还需要修改存储过程,以便在未提供参数时使用默认值(例如null),请执行以下操作:


很抱歉没有在上面的帖子中添加此评论。名声不够

您不应该以当前的方式调用存储过程。您应该使用参数。您的代码易受SQL注入的影响

永远不要对用户输入的值进行字符串压缩。

您应该有一个类似的存储过程设置:

创建过程spFoo
@name varchar(50)=‘Jim’,--默认值
@phone varchar(50)=null--可选
作为
开始
不计数;
--插入语句
结束
去
然后在代码中提供参数:

string name=this.nameTextBox.Text;
字符串phone=this.phoneTextBox.Text;
if(string.IsNullOrWhiteSpace(name))
name=null;
if(string.IsNullOrWhiteSpace(电话))
phone=null;
SqlConnection=newsqlconnection(@“”);
使用(SqlCommand=connection.CreateCommand())
{
command.CommandType=CommandType.storedProcess;
//仅将其保留为存储过程名称
command.CommandText=“spFoo”;
//如果name为null,则传递Jim(请参阅存储过程定义)
//若phone为null,则传递null(请参阅存储过程定义)
command.Parameters.AddWithValue(“@name”,name);
command.Parameters.AddWithValue(“@phone”,phone);
尝试
{
connection.Open();
int result=command.ExecuteNonQuery();
控制台写入线(结果);
}
最后
{
if(connection.State!=ConnectionState.Closed)
connection.Close();
}
}
我不确定您为什么使用Odbc名称空间对象,因为它听起来像是在使用MS-SQL。您应该使用来自
System.Data.SqlClient
命名空间的对象


实际问题的答案很可能涉及执行类似以下内容的脚本(而不是存储过程):

DECLARE@RC int
声明@name varchar(50)
声明@phone varchar(50)
--TODO:在此处设置参数值。
执行@RC=spFoo
@名字,
@电话
去

这是不推荐的。

您需要删除
设置NOCOUNT ON从存储过程中删除

从:

停止将显示受Transact-SQL语句或存储过程影响的行数计数的消息作为结果集的一部分返回

正如其他人所指出的,您也应该将查询参数化,但是
-1
是由
NOCOUNT
处于
开启状态引起的

编辑

我意识到这不是您要问的,而是要使用ODBC的参数化查询,您需要根据文档使用
作为顺序占位符。例如:

using (OdbcConnection connection = new OdbcConnection(connectionString))
{
    string sp = "{call spFoo (?, ?)}";

    using (OdbcCommand command = new OdbcCommand(sp, connection))
    {
        command.CommandType = System.Data.CommandType.StoredProcedure;

        connection.Open();
        //the order here is important, the names are not!
        command.Parameters.Add("@name", OdbcType.VarChar).Value = "test name";
        command.Parameters.Add("@phone", OdbcType.VarChar).Value = "test phone";

        Console.WriteLine(command.ExecuteNonQuery().ToString());
    }
}

修改sp,使param作为可选参数工作,然后直接从Code调用sp,因为您将命令文本设置为过程的名称。然后,您需要为每个参数向命令中添加参数。过程是什么?表的结构是怎样的?首先,若变量的值未通过过程传递,是否将默认值用作nulll。在insert的情况下,您的表是否允许空值在存储过程中?如果是这样,您应该删除它,因为它将阻止SQL Server从SP返回受影响行的计数。仅此而已!我把它去掉,开始拿回1。当我检查数据库时,我有一堆空记录。我想服务器需要一段时间才能告诉我它有一个新记录。回答这个问题,我会给你评分,@petelids。这让情况更糟:过程或函数“spFoo”需要参数“@name”,但没有提供该参数。@TravisHeeter这是因为你需要在存储过程中添加一个名为
@name
的参数。我的存储过程:插入spFoo(name,phone)值(@name,@phone)。虽然我已通过“spFoo expects”错误,但仍然得到-1。@TravisHeeter我希望您的表名与存储过程名不同。尝试了所有这些后,仍然无效。我觉得每个人都在谈论我“应该”做什么,而忽略了真正的问题。好吧,我重写了我的整个函数和存储过程,我仍然得到了-1。我现在有了你在这里写的东西(较长的版本,而不是脚本)。编辑,尽管我还没有尝试SqlClient。我认为您不能将dsn与SqlClient一起使用。尝试过的SqlClient确实不能将dsn与SqlClient一起使用。如果您想知道,您不能在odbc中以相同的方式使用参数:通过参数添加变量对我无效,因为我使用的是OdbcCommand。我是乌西
using (OdbcConnection connection = new OdbcConnection(connectionString))
{
    string sp = "{call spFoo (?, ?)}";

    using (OdbcCommand command = new OdbcCommand(sp, connection))
    {
        command.CommandType = System.Data.CommandType.StoredProcedure;

        connection.Open();
        //the order here is important, the names are not!
        command.Parameters.Add("@name", OdbcType.VarChar).Value = "test name";
        command.Parameters.Add("@phone", OdbcType.VarChar).Value = "test phone";

        Console.WriteLine(command.ExecuteNonQuery().ToString());
    }
}