【问题标题】:Stored Procedure unused parameter show error存储过程未使用的参数显示错误
【发布时间】:2014-04-24 08:10:15
【问题描述】:

收到的错误是:

过程或函数 SPCustomerDetails 需要参数“@address”,但未提供该参数。

说明:在执行当前 Web 请求期间发生未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。

异常详细信息:System.Data.SqlClient.SqlException:过程或函数“SPCustomerDetails”需要参数“@address”,但未提供。

我的存储过程是:

ALTER  PROCEDURE [dbo].[SPCustomerDetails]
(
@id varchar,
@title varchar(50),
@fname varchar(50),
@Lname varchar(50),
@mob varchar(50),
@email varchar(50),
@password varchar(50),
@address varchar(50),
@altemail varchar(50),
@gender varchar(50),
@dob varchar(50),
@city varchar(50),
@country varchar(50),
@state varchar(50),
@checked varchar(50),
@opr varchar(50)

)
as
begin
    if @opr='BTNNEW'
    INSERT INTO TblCustomer_Details
    (FName,LName,Email,Password,Contact_No,checked)
     VALUES
     (@fname,@Lname,@email,@password,@mob,@checked)

     else if @opr='BTNUPDATE'
     Update  TblCustomer_Details 
     set
        Title=@title,
        FName=@fname,
        LName=@Lname,
        Email=@email,
        alt_Email=@altemail,
        Address=@address,
        Password=@password,
        Gender=@gender,
        DOB=@dob,
        Contact_No=@mob,
        Country=@country,
        State=@state,
        City=@city
        where 
        Cust_ID=@id

    else if @opr='BTNDELETE'
    delete TblCustomer_Details 
    from TblCustomer_Details
    where
    Cust_ID=@id

执行程序:

con.ExeQry(" exec SPCustomerDetails '" + fname.Text.Trim() + "',N'" + 
  lname.Text.Trim() + "',N'" + pemail.Text.Trim() + "',N'" + 
  cpassword.Text.Trim() + "',N'" + mobile.Text.Trim() + "',N'" + 
  offers.Checked + "','" + opr.ToUpper() + "'");

【问题讨论】:

  • 您的 proc 有 16 个强制参数,而您似乎只传递了大约 7 个。另外,参数化!
  • 您实际上并没有提出问题,您只是发布了一个错误和一些代码;即使看起来没有必要,但它仍然是礼貌的。
  • 但我想在第一次只传递 7 个参数,那我能做什么?
  • 如果您不要求该参数,请传递 null

标签: asp.net stored-procedures


【解决方案1】:

试试这个技巧:-

    CREATE PROCEDURE ProcName

    @Parameter1 VARCHAR (100) = NULL
AS

/* check for the NULL */ 
if (@Parameter1 IS NULL)
BEGIN
    /* your code*/

END

/* In Query*/
SELECT *
FROM Table
WHERE Column = @Parameter1

【讨论】:

  • 你能解释一下这如何帮助回答最初的问题吗?
  • @Adrian Wragg 他只想传递几个参数,我认为使用上述技术很容易只传递所需的参数。
【解决方案2】:
con.ExeQry(" exec SPCustomerDetails '" + fname.Text.Trim() + "',N'" + lname.Text.Trim() + "',N'" + pemail.Text.Trim() + "',N'" + cpassword.Text.Trim() + "',N'" + mobile.Text.Trim() + "',N'" + offers.Checked + "','" + opr.ToUpper() + "'");

你在 con.ExeQry 中给出的字符串如下所示

exec SPCustomerDetails 'fname',N'lname',N'mobile',N'pemail',N'pwd',N'offers','opr'

它抛出 sql 异常

这里我取 fname.Text.Trim() =fname,lname.Text.Trim()=lname......

应该是这样的

exec SPCustomerDetails 'fname','Nlname','Npemail','Npwd','Nmovile','Noffers','opr'

你说你第一次传递了7个参数。所以第一次传递NULL,你不想这样传递参数

exec SPCustomerDetails NULL,NULL,'fname','Nlname',NULL,'Npemail','Npwd',NULL,'Nmovile','Noffers',NULL,NULL,NULL,NULL,NULL,'opr'

我只是用 sqlquery 样式编写查询,将其转换为您的 Asp.net 样式

喜欢 con.ExeQry(" exec SPCustomerDetails .....

您在传递参数时给出了不同的顺序,您应该按照您在存储过程中提到的方式给出参数

【讨论】:

    【解决方案3】:

    您的问题是您希望将某些字段声明为可选。不幸的是,在给出的代码中,您似乎假设 SQL 将根据您传递给 SPCustomerDetails 的调用的变量名称来“解决”您的意思。

    您的存储过程调用只会解析为:

    exec SPCustomerDetails 'Bob', N'Smith', N'bob@sample.com', N'hunter2',
        N'07111 1234', N'True', 'True'
    

    将传入以填充前七个参数;第八个,@address,将是第一个没有价值的,因此你看到的错误。

    如果您希望在存储过程调用中使用默认值(因此是可选的),您可以通过将默认值放在参数后面来在过程定义中声明它;例如:

    ALTER  PROCEDURE [dbo].[SPCustomerDetails]
    (
        @id varchar,
        @title varchar(50) = null,
        @fname varchar(50),
        ...
    

    不需要传入@title 字段。您还需要更改存储过程调用以直接填充各个参数。您的数据库调用需要读取:

    exec SPCustomerDetails @fname = 'Bob',
                           @lname = 'Smith',
                           @email = 'bob@sample.com'
    

    或者,在代码中:

    con.ExeQry(" exec SPCustomerDetails @fname = '" + fname.Text.Trim() + "'," +
                                      " @lname = '" + lname.Text.Trim() + "'," +
                                      " @email = '" + email.Text.Trim() + "'," +
    ...
    

    也就是说,此代码还有两个其他问题也应该解决,这些问题的修复超出了此答案的范围:

    1. 您应该参数化您的存储过程调用,而不是直接将所有内容编码为单个字符串;原样的代码让您很容易受到 SQL 注入攻击。
    2. 根据我看到的代码,您直接从用户界面获取密码并将其存储在数据库中。您应该从不以纯文本形式存储密码;至少应该对其进行散列和加盐处理。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-15
      • 2013-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多