2008-12-15 452 views
90

在SQL Server中訪問存儲過程時,我發現了錯誤參數過程需要但未提供

Server Error in '/' Application. 
Procedure or function 'ColumnSeek' expects parameter '@template', which was not supplied. 

,當我通過.NET的數據連接到SQL調用存儲過程的參數這是發生即使我提供參數,也是如此。這是我的代碼。

SqlConnection sqlConn = new SqlConnection(connPath); 
sqlConn.Open(); 

//METADATA RETRIEVAL 
string sqlCommString = "QCApp.dbo.ColumnSeek"; 
SqlCommand metaDataComm = new SqlCommand(sqlCommString, sqlConn); 
metaDataComm.CommandType = CommandType.StoredProcedure; 
SqlParameter sp = metaDataComm.Parameters.Add("@template",SqlDbType.VarChar,50); 
sp.Value = Template; 

SqlDataReader metadr = metaDataComm.ExecuteReader(); 

而且我的存儲過程是:

USE [QCApp] 
    GO 
    SET ANSI_NULLS ON 
    GO 
    SET QUOTED_IDENTIFIER ON 
    GO 

    ALTER PROCEDURE [dbo].[ColumnSeek] 
     @template varchar(50) 
    AS 
    EXEC('SELECT Column_Name, Data_Type 
    FROM [QCApp].[INFORMATION_SCHEMA].[COLUMNS] 
    WHERE TABLE_NAME = ' + @template); 

我試圖找出我在做什麼錯在這裏。

編輯:事實證明,模板爲空,因爲我是從通過URL傳遞參數獲取其價值,我搞砸了網址PARAM傳遞(我用的是@並代替&

+0

非常古老的問題,但我遇到了同樣的問題,在我的情況下,我沒有看到我在@parameter之一中添加了額外的空間。一小時的調試。 – 2012-06-16 04:31:43

+0

請參閱http://stackoverflow.com/a/26374810/1860652執行存儲過程並獲取此錯誤 – AlexFoxGill 2014-12-16 15:50:57

回答

74

我會檢查我的應用程序代碼,看看您設置@template的值是什麼。我懷疑它是無效的,其中存在問題。

+28

啊,舊的零vs DbNull.Value板栗... – 2008-12-15 15:21:51

0

首先 - 爲什麼是EXEC?不應該只是

AS 
SELECT Column_Name, ... 
FROM ... 
WHERE TABLE_NAME = @template 

當前的SP沒有意義嗎?特別是,它會尋找匹配@template的,而不是@template的varchar值。即如果@template是'Column_Name',它會搜索WHERE TABLE_NAME = Column_Name,這是非常罕見的(要將表和列命名爲相同)。

此外,如果你做的使用動態SQL,你應該使用EXEC sp_ExecuteSQL(保持值作爲參數)從注入攻擊(而不是輸入的連接)來防止。但在這種情況下並不需要。

重新提出實際問題 - 它一目瞭然;你確定你沒有不同的SP副本嗎?這是一個常見的錯誤...

+0

它仍然不適用於此更改。 我有執行,因爲我以前工作與一個proc從哪裏提供從一個參數,所以我在這個問題上思考錯誤。但我仍然得到錯誤,只有選擇 – 2008-12-15 15:19:01

+0

非常好奇;也許三重檢查錯別字? – 2008-12-15 15:21:09

3

如果未設置Template(即== null),則也會引發此錯誤。

更多評論:

如果你知道你所添加參數的時間參數值,還可以使用AddWithValue

的EXEC不是必需的。您可以直接在SELECT中引用@template參數。

250

除了其他的答案在這裏,如果你忘了放:

cmd.CommandType = CommandType.StoredProcedure; 

那麼你也將獲得此錯誤。

4

我碰到過類似的問題,同時調用存儲過程

CREATE PROCEDURE UserPreference_Search 
    @UserPreferencesId int, 
    @SpecialOfferMails char(1), 
    @NewsLetters char(1), 
    @UserLoginId int, 
    @Currency varchar(50) 
AS 
DECLARE @QueryString nvarchar(4000) 

SET @QueryString = 'SELECT UserPreferencesId,SpecialOfferMails,NewsLetters,UserLoginId,Currency FROM UserPreference' 
IF(@UserPreferencesId IS NOT NULL) 
BEGIN 
SET @QueryString = @QueryString + ' WHERE UserPreferencesId = @DummyUserPreferencesId'; 
END 

IF(@SpecialOfferMails IS NOT NULL) 
BEGIN 
SET @QueryString = @QueryString + ' WHERE SpecialOfferMails = @DummySpecialOfferMails'; 
END 

IF(@NewsLetters IS NOT NULL) 
BEGIN 
SET @QueryString = @QueryString + ' WHERE NewsLetters = @DummyNewsLetters'; 
END 

IF(@UserLoginId IS NOT NULL) 
BEGIN 
SET @QueryString = @QueryString + ' WHERE UserLoginId = @DummyUserLoginId'; 
END 

IF(@Currency IS NOT NULL) 
BEGIN 
SET @QueryString = @QueryString + ' WHERE Currency = @DummyCurrency'; 
END 

EXECUTE SP_EXECUTESQL @QueryString 
        ,N'@DummyUserPreferencesId int, @DummySpecialOfferMails char(1), @DummyNewsLetters char(1), @DummyUserLoginId int, @DummyCurrency varchar(50)' 
        ,@[email protected] 
        ,@[email protected] 
        ,@[email protected] 
        ,@[email protected] 
        ,@[email protected]; 

動態地構造查詢搜索我是通過調用上面一個:

public DataSet Search(int? AccessRightId, int? RoleId, int? ModuleId, char? CanAdd, char? CanEdit, char? CanDelete, DateTime? CreatedDatetime, DateTime? LastAccessDatetime, char? Deleted) 
    { 
     dbManager.ConnectionString = ConfigurationManager.ConnectionStrings["MSSQL"].ToString(); 
     DataSet ds = new DataSet(); 
     try 
     { 
      dbManager.Open(); 
      dbManager.CreateParameters(9); 
      dbManager.AddParameters(0, "@AccessRightId", AccessRightId, ParameterDirection.Input); 
      dbManager.AddParameters(1, "@RoleId", RoleId, ParameterDirection.Input); 
      dbManager.AddParameters(2, "@ModuleId", ModuleId, ParameterDirection.Input); 
      dbManager.AddParameters(3, "@CanAdd", CanAdd, ParameterDirection.Input); 
      dbManager.AddParameters(4, "@CanEdit", CanEdit, ParameterDirection.Input); 
      dbManager.AddParameters(5, "@CanDelete", CanDelete, ParameterDirection.Input); 
      dbManager.AddParameters(6, "@CreatedDatetime", CreatedDatetime, ParameterDirection.Input); 
      dbManager.AddParameters(7, "@LastAccessDatetime", LastAccessDatetime, ParameterDirection.Input); 
      dbManager.AddParameters(8, "@Deleted", Deleted, ParameterDirection.Input); 
      ds = dbManager.ExecuteDataSet(CommandType.StoredProcedure, "AccessRight_Search"); 
      return ds; 
     } 
     catch (Exception ex) 
     { 
     } 
     finally 
     { 
      dbManager.Dispose(); 
     } 
     return ds; 
    } 

很多頭,然後進行搔抓我修改過的存儲程序爲:

ALTER PROCEDURE [dbo].[AccessRight_Search] 
    @AccessRightId int=null, 
    @RoleId int=null, 
    @ModuleId int=null, 
    @CanAdd char(1)=null, 
    @CanEdit char(1)=null, 
    @CanDelete char(1)=null, 
    @CreatedDatetime datetime=null, 
    @LastAccessDatetime datetime=null, 
    @Deleted char(1)=null 
AS 
DECLARE @QueryString nvarchar(4000) 
DECLARE @HasWhere bit 
SET @HasWhere=0 

SET @QueryString = 'SELECT a.AccessRightId, a.RoleId,a.ModuleId, a.CanAdd, a.CanEdit, a.CanDelete, a.CreatedDatetime, a.LastAccessDatetime, a.Deleted, b.RoleName, c.ModuleName FROM AccessRight a, Role b, Module c WHERE a.RoleId = b.RoleId AND a.ModuleId = c.ModuleId' 

SET @HasWhere=1; 

IF(@AccessRightId IS NOT NULL) 
    BEGIN 
     IF(@HasWhere=0) 
      BEGIN 
       SET @QueryString = @QueryString + ' WHERE a.AccessRightId = @DummyAccessRightId'; 
       SET @HasWhere=1; 
      END 
     ELSE    SET @QueryString = @QueryString + ' AND a.AccessRightId = @DummyAccessRightId'; 
    END 

IF(@RoleId IS NOT NULL) 
    BEGIN 
     IF(@HasWhere=0) 
      BEGIN 
       SET @QueryString = @QueryString + ' WHERE a.RoleId = @DummyRoleId'; 
       SET @HasWhere=1; 
      END 
     ELSE   SET @QueryString = @QueryString + ' AND a.RoleId = @DummyRoleId'; 
    END 

IF(@ModuleId IS NOT NULL) 
BEGIN 
    IF(@HasWhere=0) 
      BEGIN 
       SET @QueryString = @QueryString + ' WHERE a.ModuleId = @DummyModuleId'; 
       SET @HasWhere=1; 
      END 
    ELSE SET @QueryString = @QueryString + ' AND a.ModuleId = @DummyModuleId'; 
END 

IF(@CanAdd IS NOT NULL) 
BEGIN 
    IF(@HasWhere=0) 
      BEGIN  
       SET @QueryString = @QueryString + ' WHERE a.CanAdd = @DummyCanAdd'; 
       SET @HasWhere=1; 
      END 
    ELSE SET @QueryString = @QueryString + ' AND a.CanAdd = @DummyCanAdd'; 
END 

IF(@CanEdit IS NOT NULL) 
BEGIN 
    IF(@HasWhere=0) 
     BEGIN 
      SET @QueryString = @QueryString + ' WHERE a.CanEdit = @DummyCanEdit'; 
      SET @HasWhere=1; 
     END 
    ELSE SET @QueryString = @QueryString + ' AND a.CanEdit = @DummyCanEdit'; 
END 

IF(@CanDelete IS NOT NULL) 
BEGIN 
    IF(@HasWhere=0) 
     BEGIN 
      SET @QueryString = @QueryString + ' WHERE a.CanDelete = @DummyCanDelete'; 
      SET @HasWhere=1; 
     END 
    ELSE SET @QueryString = @QueryString + ' AND a.CanDelete = @DummyCanDelete'; 
END 

IF(@CreatedDatetime IS NOT NULL) 
BEGIN 
    IF(@HasWhere=0) 
    BEGIN 
     SET @QueryString = @QueryString + ' WHERE a.CreatedDatetime = @DummyCreatedDatetime'; 
     SET @HasWhere=1; 
    END 
    ELSE SET @QueryString = @QueryString + ' AND a.CreatedDatetime = @DummyCreatedDatetime'; 
END 

IF(@LastAccessDatetime IS NOT NULL) 
BEGIN 
    IF(@HasWhere=0) 
     BEGIN 
      SET @QueryString = @QueryString + ' WHERE a.LastAccessDatetime = @DummyLastAccessDatetime'; 
      SET @HasWhere=1; 
     END 
    ELSE SET @QueryString = @QueryString + ' AND a.LastAccessDatetime = @DummyLastAccessDatetime'; 
END 

IF(@Deleted IS NOT NULL) 
BEGIN 
    IF(@HasWhere=0) 
    BEGIN 
     SET @QueryString = @QueryString + ' WHERE a.Deleted = @DummyDeleted'; 
     SET @HasWhere=1; 
    END 
    ELSE SET @QueryString = @QueryString + ' AND a.Deleted = @DummyDeleted'; 
END 

PRINT @QueryString 

EXECUTE SP_EXECUTESQL @QueryString 
         ,N'@DummyAccessRightId int, @DummyRoleId int, @DummyModuleId int, @DummyCanAdd char(1), @DummyCanEdit char(1), @DummyCanDelete char(1), @DummyCreatedDatetime datetime, @DummyLastAccessDatetime datetime, @DummyDeleted char(1)' 
         ,@[email protected] 
         ,@[email protected] 
         ,@[email protected] 
         ,@[email protected] 
         ,@[email protected] 
         ,@[email protected] 
         ,@[email protected] 
         ,@[email protected] 
         ,@[email protected]; 

這裏我正在初始化輸入參數的存儲過程清零如下

@AccessRightId int=null, 
@RoleId int=null, 
@ModuleId int=null, 
@CanAdd char(1)=null, 
@CanEdit char(1)=null, 
@CanDelete char(1)=null, 
@CreatedDatetime datetime=null, 
@LastAccessDatetime datetime=null, 
@Deleted char(1)=null 

對我做了詭計。

我希望這會對陷入類似陷阱的人有幫助。

26

此問題確實通常是由於將參數值設置爲null而導致的,如上面提到的HLGEM。我想我會詳細闡述一些解決這個問題的方法,我發現這些問題的解決方案對於那些新來解決這個問題的人有益。

,我更喜歡的解決方案是將存儲過程的參數默認爲NULL(或任何價值,你想要的),這是由上述SANGRAM提及,但可能會錯過,因爲答案是非常詳細。沿着線的東西:

CREATE PROCEDURE GetEmployeeDetails 
    @DateOfBirth DATETIME = NULL, 
    @Surname  VARCHAR(20), 
    @GenderCode  INT = NULL, 
AS 

這意味着,如果參數最終在代碼被設置在某些條件下爲空,.NET將不設置參數,然後該存儲的過程將用它的缺省值是定義。另一種解決辦法,如果你真的想解決代碼中的問題,是使用處理該問題對您的擴展方法,像:

public static SqlParameter AddParameter<T>(this SqlParameterCollection parameters, string parameterName, T value) where T : class 
{ 
    return value == null ? parameters.AddWithValue(parameterName, DBNull.Value) : parameters.AddWithValue(parameterName, value); 
} 

馬特漢密爾頓有一個很好的職位here是列出了一些更偉大的處理這一領域的擴展方法。

9

我有一個問題,當我將0提供給一個整數參數時,我會得到錯誤。結果發現:

cmd.Parameters.AddWithValue("@Status", 0); 

作品,但這並不:

cmd.Parameters.Add(new SqlParameter("@Status", 0)); 
0

我有同樣的問題,解決它只是給你的參數集合添加完全相同的參數名稱作爲存儲過程。

比方說,你創建一個存儲過程:

create procedure up_select_employe_by_ID 
    (@ID int) 
as 
    select * 
    from employe_t 
    where employeID = @ID 

所以一定要命名您的參數,正是因爲它是在你的存儲過程,這將是

cmd.parameter.add("@ID", sqltype,size).value = @ID 

如果你去

cmd.parameter.add("@employeID", sqltype,size).value = @employeid 

然後發生錯誤。

4

對於我的情況,我必須通過DBNULL.Value(使用if else條件)存儲過程代碼參數,這些參數沒有定義,但值爲null

0

當空值傳遞給我的存儲過程的參數時,我今天遇到了這個錯誤。通過添加默認值= null,我可以輕鬆地修改存儲過程。

相關問題