프로 시저에 제공되지 않은 매개 변수가 필요합니다.
SQL Server에서 저장 프로 시저에 액세스 할 때 오류가 발생합니다.
Server Error in '/' Application.
Procedure or function 'ColumnSeek' expects parameter '@template', which was not supplied.
이것은 매개 변수를 (System.data.SqlClient)
제공하더라도 .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을 통해 전달 된 매개 변수에서 값을 얻었고 전달하는 URL 매개 변수를 망 쳤기 때문에 템플릿이 null이었습니다 ( @
대신 for 및 대신 사용 &
)
내 응용 프로그램 코드를 확인하고 @template을 설정하는 값을 확인합니다. 나는 그것이 무효라고 생각하고 거기에 문제가 있습니다.
여기에 다른 답변 외에도 다음을 입력하는 것을 잊은 경우 :
cmd.CommandType = CommandType.StoredProcedure;
그러면이 오류도 발생합니다.
이 문제는 실제로 위에서 언급 한 HLGEM 과 같이 매개 변수 값을 null로 설정하여 발생합니다 . 나는이 문제에 대해 처음 접하는 사람들의 이익을 위해 유용하다고 판단한이 문제에 대한 몇 가지 해결책에 대해 자세히 설명 할 것이라고 생각했습니다.
내가 선호하는 솔루션은 저장 프로 시저 매개 변수를 NULL (또는 원하는 값)로 기본 설정하는 것입니다. 이는 위의 sangram 에서 언급 했지만 대답이 매우 장황하기 때문에 놓칠 수 있습니다. 라인을 따라 뭔가 :
CREATE PROCEDURE GetEmployeeDetails
@DateOfBirth DATETIME = NULL,
@Surname VARCHAR(20),
@GenderCode INT = NULL,
AS
즉, 일부 조건에서 매개 변수가 코드에서 null로 설정되면 .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);
}
매트 해밀턴은 좋은 게시물을 가지고 여기에 목록이 좀 더 큰 확장 방법이 지역을 처리 할 때있다.
정수 매개 변수에 0을 제공하면 오류가 발생하는 문제가 발생했습니다. 그리고 다음을 발견했습니다.
cmd.Parameters.AddWithValue("@Status", 0);
작동하지만 그렇지 않습니다.
cmd.Parameters.Add(new SqlParameter("@Status", 0));
저장 프로 시저를 호출하는 동안 비슷한 문제가 발생합니다.
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)'
,@DummyUserPreferencesId=@UserPreferencesId
,@DummySpecialOfferMails=@SpecialOfferMails
,@DummyNewsLetters=@NewsLetters
,@DummyUserLoginId=@UserLoginId
,@DummyCurrency=@Currency;
위의 검색 쿼리를 동적으로 구성하는 것은 다음과 같습니다.
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)'
,@DummyAccessRightId=@AccessRightId
,@DummyRoleId=@RoleId
,@DummyModuleId=@ModuleId
,@DummyCanAdd=@CanAdd
,@DummyCanEdit=@CanEdit
,@DummyCanDelete=@CanDelete
,@DummyCreatedDatetime=@CreatedDatetime
,@DummyLastAccessDatetime=@LastAccessDatetime
,@DummyDeleted=@Deleted;
HERE I am Initializing the Input Params of Stored Procedure to null as Follows
@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
that did the trick for Me.
I hope this will be helpfull to someone who fall in similar trap.
For my case, I had to pass DBNULL.Value
(using if else condition) from code for stored procedures parameter that are not defined null
but value is null
.
If Template is not set (i.e. ==null), this error will be raised, too.
More comments:
If you know the parameter value by the time you add parameters, you can also use AddWithValue
The EXEC is not required. You can reference the @template parameter in the SELECT directly.
First - why is that an EXEC? Shouldn't that just be
AS
SELECT Column_Name, ...
FROM ...
WHERE TABLE_NAME = @template
The current SP doesn't make sense? In particular, that would look for a column matching @template, not the varchar value of @template. i.e. if @template is 'Column_Name'
, it would search WHERE TABLE_NAME = Column_Name
, which is very rare (to have table and column named the same).
Also, if you do have to use dynamic SQL, you should use EXEC sp_ExecuteSQL
(keeping the values as parameters) to prevent from injection attacks (rather than concatenation of input). But it isn't necessary in this case.
Re the actual problem - it looks OK from a glance; are you sure you don't have a different copy of the SP hanging around? This is a common error...
I came across this error today when null values were passed to my stored procedure's parameters. I was able easily fix by altering the stored procedure by adding default value = null.
I had the same issue, to solve it just add exactly the same parameter name to your parameter collection as in your stored procedures.
Example
Let's say you create a stored procedure:
create procedure up_select_employe_by_ID
(@ID int)
as
select *
from employe_t
where employeID = @ID
So be sure to name your parameter exactly as it is in your stored procedure this would be
cmd.parameter.add("@ID", sqltype,size).value = @ID
if you go
cmd.parameter.add("@employeID", sqltype,size).value = @employeid
then the error happens.
It is necessary to tell that a Stored Proc is being called:
comm.CommandType = CommandType.StoredProcedure;
참고URL : https://stackoverflow.com/questions/368642/procedure-expects-parameter-which-was-not-supplied
'programing tip' 카테고리의 다른 글
디렉토리의 대소 문자를 변경했는데 Git이 선택하지 않는 것 같습니다. (0) | 2020.08.17 |
---|---|
ConstraintLayout 내부의 Wrap_content 뷰가 화면 밖으로 확장됩니다. (0) | 2020.08.17 |
자신을 반복하지 않고 삼항 연산자 (일명 if) 표현식을 작성하는 방법 (0) | 2020.08.17 |
Android ImageView 확대 및 축소 (0) | 2020.08.17 |
const char * const 대 const char *? (0) | 2020.08.17 |