Stored procedure has too many parameters when being called [duplicate] - c#

This question already has answers here:
"Procedure or function has too many arguments specified" But It Doesn't
(3 answers)
Closed 8 years ago.
I have a stored procedure with parameters:
ALTER PROCEDURE [dbo].[prAddSortament]
#Name varchar(255),
#ProcessingId varchar(35),
#ShapeId varchar(35),
#GostId varchar(35),
#PartOfId varchar(35),
#DescrArr varchar(max),--varbinary,
#tsVal varchar(max),
#SM varchar(max)
AS
BEGIN
And I'm calling it from my program that way:
using (SqlConnection con = new SqlConnection(Properties.Settings.Default.MiSConStr))
{
SqlCommand cmd = new SqlCommand("dbo.prAddSortament", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#Name", sort.Name);
cmd.Parameters.AddWithValue("#ProcessingId", sort.Processing.ObjectId);
cmd.Parameters.AddWithValue("#ShapeId", sort.Shap.ObjectId);
cmd.Parameters.AddWithValue("#GostId", sort.Gost);
cmd.Parameters.AddWithValue("#PartOfId", sort.PartOf);
cmd.Parameters.AddWithValue("#DescrArr", sort.Description);
cmd.Parameters.AddWithValue("#tsVal", ts);
cmd.Parameters.AddWithValue("#SM", sortMat);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
On cmd.ExeccutrNonQuery(); I have an exception
Procedure or function prAddSortament has too many arguments specified.
Can anybody help me?

If the number of parameters are same then try to check their types. It looks like there is some mismatch of the data types of the parameters.

Add below code it will specify the stored procedure you want to add :-
cmd.CommandText = "prAddSortament";
Extra info for this kind of error as detailed here http://www.sql-server-helper.com/error-messages/msg-8144.aspx :-
SQL Server Error Messages - Msg 8144
Error Message: Server: Msg 8144, Level 16, State 2, Procedure Stored
Procedure or Function Name, Line 0 Procedure or function Stored
Procedure or Function Name has too many arguments specified.
Causes:
As the message describes, this error is encountered when you are
passing arguments or parameters to a function or stored procedure
which is more than what the function or stored procedure is expecting.
To illustrate, let’s say you have the following function definition:
> CREATE FUNCTION [dbo].[ufn_Concat] ( #pString1 VARCHAR(10), #pString2
> VARCHAR(10) ) RETURNS VARCHAR(20) AS BEGIN
> RETURN ISNULL(#pString1 + ' ', '') + ISNULL(#pString2, '') END
This function expects only 2 arguments, namely #pString1 and
> #pString2. To use this function, you do the following: SELECT
> [dbo].[ufn_Concat] ( [FirstName], [LastName] ) AS [FullName] FROM
> [dbo].[Customers]
The error will be encountered you pass more than 2 arguments or
> parameters to the function, as follows: SELECT [dbo].[ufn_Concat] (
> [FirstName], [MiddleName], [LastName] ) AS [FullName] FROM
> [dbo].[Customers]
>
Server: Msg 8144, Level 16, State 2, Line 1 Procedure or function
dbo.ufn_Concat has too many arguments specified.
Solution/Workaround:
To avoid this error from happening, always make sure that you pass the
same number of arguments that a stored procedure or function is
expecting. To know the parameters expected by a stored procedure, you
can use the sp_help system stored procedure and pass the name of the
stored procedure as the parameter.

That was my great fault. I'm using two versions of database, and in the connection string was specified old version of DB, where dbo.prAddSortament exists but have less parameters.

Related

SQL output procedure C# ExecuteNonQuery "parameter not supplied" [duplicate]

This question already has answers here:
Stored procedure or function expects parameter which is not supplied
(7 answers)
Closed last year.
This question has not been already answered. Similar question "Stored procedure or function expects parameter which is not supplied" is a different question about how to code the request in C#. My issue is an SQL issue. I am getting an error
parameter not supplied
inconsistently. If I am executing a stored procedure from SSMS with the following script, it works fine with the expected output:
declare #p5 int
execute dbo.aspCreateQuote #customerID = 13,#itemList='text goes here',#quoteID = #p5 output;
select #p5
The following script (from SQL Server Profiler) executed by an app does not work:
declare #p5 int
set #p5=NULL
exec sp_executesql N'psa.dbo.aspCreateQuote',N'#customerID int,#itemList varchar(3774), #quoteID int output'
,#customerID=13
,#itemList='[xml block of text goes here]',
#quoteID=#p5 output
select #p5
It generates the error:
'aspCreateQuote' expects parameter '#customerID', which was not supplied.
Clearly the parameter is supplied and is not null, so what's wrong?
The second script is generated by C# / ASP.NET SqlCommand.ExecuteNonQuery method as revealed by SQL Server Profiler. If there is something wrong with the script, then how to get C# to generate the correct script?
Here is the procedure:
ALTER PROCEDURE [dbo].[aspCreateQuote]
#customerID int,
#itemList xml,
#quoteID int OUTPUT
AS
INSERT INTO Quotes (CustomerID, Items)
VALUES (#customerID, #itemList);
SET #quoteID = (SELECT MAX(QuoteID) FROM Quotes WHERE CustomerID = #customerID);
RETURN #quoteID
And here is the C#:
SqlCommand sp = new SqlCommand("dbo.aspCreateQuote", cnx);
SqlParameterCollection parameterSet = sp.Parameters;
SqlParameter param;
param = new SqlParameter("#customerID", SqlDbType.Int);
param.Value = Convert.ToInt32(cartID);
parameterSet.Add(param);
param = new SqlParameter("#itemList", SqlDbType.VarChar);
param.Value = string.IsNullOrEmpty(xmlItems) ? "" : xmlItems;
parameterSet.Add(param);
param = new SqlParameter("#quoteID", SqlDbType.Int);
param.Value = 0;
param.Direction = ParameterDirection.Output;
parameterSet.Add(param);
sp.ExecuteNonQuery();
quoteID = (Int32)sp.Parameters["#QuoteID"].Value;
Thank you for your help.
You need to list the parameters as part of the #stmt value because that needs to be the exact SQL you wish to execute e.g.
declare #p5 int;
set #p5 = null;
exec sp_executesql N'dbo.aspCreateQuote #customerID, #itemList, #quoteID'
, N'#customerID int, #itemList varchar(3774), #quoteID int output'
, #customerID=13
, #itemList='[xml block of text goes here]'
, #quoteID=#p5 output;
select #p5;
FYI, using the RETURN statement for returning user values is not its intended use. The RETURN statement is for returning a status of the stored procedure.

Must declare scalar variable when passing bool

SQL Server is 2014. Visual Studio 2017.
I am trying to pass 3 parameters to SQL Server, but getting this error:
System.Data.SqlClient.SqlException: 'Must declare the scalar variable "#Title1Item".'
I've included both the C# and SQL Server side code. Can anyone tell me what I am doing wrong?
public DataTable GetInventoryByAssetDescription (string Desc, string DispositionText, bool Title1Item) {
DataTable myRecords = new DataTable();
using (SqlConnection cn = new SqlConnection (ConnectionString)) {
// Specify which stored procedure to use and add a parameter.
SqlCommand cmd = new SqlCommand ("GetInventoryByAssetDescription", cn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue ("#SearchString", Desc);
cmd.Parameters.AddWithValue ("#DispositionText", DispositionText);
cmd.Parameters.AddWithValue ("#Title1Item", Title1Item);
SqlDataAdapter da = new SqlDataAdapter (cmd);
cn.Open();
da.Fill (myRecords);
}
ALTER PROCEDURE [dbo].[GetInventoryByAssetDescription] (
#SearchString varchar(30),
#DispositionText varchar(200),
#Title1Item bit
)
I expect the 3 parameters to be passed through to the stored procedure, but am getting this error on the da.fill (myRecords) line:
System.Data.SqlClient.SqlException: 'Must declare the scalar variable "#Title1Item".'
EDIT: So sorry, guys. Rusty old programmer here. Stored procedure code:
USE [Inventory]
GO
/****** Object: StoredProcedure [dbo].[GetInventoryByAssetDescription] Script Date: 6/4/2019 8:30:15 AM ******/
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER OFF
GO
ALTER PROCEDURE [dbo].[GetInventoryByAssetDescription]
(
#SearchString varchar(30),
#DispositionText varchar(200),
#Title1Item bit
)
AS
begin
SET NOCOUNT ON
declare #sql nvarchar (2000)
select #SearchString=UPPER(#SearchString)
set #sql = ' select in_eq_ID,
in_eq_TagNumber as TagNumber,
Title1Item,
in_eq_AssetDescription as Description,
in_eq_ExtendedDescription as ExtendedDescription,
in_eq_SerialNumber as SerialNumber,
in_eq_ValuationAmount as TotalValue,
in_eq_CustodianName as Name,
in_eq_ComplexBuilding as ShortLocation,
in_eq_SubLocationCode as ShortRoomNumber,
in_ca_Categories.in_ca_CategoryName as CategoryName,
in_eq_DispositionDate as DispositionDate,
DATEADD (dd, 0, DATEDIFF (dd, 0, in_eq_Equipment.in_eq_AcquisitionDate)) as AcquisitionDate
from in_eq_Equipment
LEFT JOIN in_ca_Categories ON in_eq_Equipment.in_eq_CategoryID_fk = in_ca_Categories.in_ca_CategoryID
where #Title1Item = Title1Item
AND upper (in_eq_AssetDescription) LIKE upper ('''+ #SearchString + ''')'
set #sql=#sql+' ' + ISNULL(#DispositionText,' ') + ' order by in_eq_AssetDescription'
execute (#sql)
return
end
When you use the datatype BIT in SQLServer as SP parameter, from C# you have to send the values 1 or 0 not true or false so you have to convert bool to int (1 for true and 0 for false)
For example
cmd.Parameters.AddWithValue ("#Title1Item", Title1Item ? 1 : 0);
or
cmd.Parameters.AddWithValue ("#Title1Item", (int)Title1Item);
Right; the problem is your SP, not the C# code. It cannot work in the way written. Parameters and local variables are not "ambient" - they won't be defined inside an EXEC or EXECUTE block, because they are not scoped in there. In some cases there is sp_executesql that allows you to pass through parameters/values by declaring them and adding them as additional parameters, but in your case this would not be a good idea, because fundamentally you are doing something incredibly dangerous, i.e. concatenating inputs to create SQL. Your stored procedure right now is a SQL injection hole and could be used to take over your server with minimal effort. If you're OK with having your data stolen and your database destroyed, you could inline/concatenate #Title1Item just like you did with the others, but: this is a terrible idea and it will hurt you.

One function for multiple stored procedures C#

I have a function that executes stored procedures. The thing is, I wish to use this one function for multiple stored procedures that take different arguments.
Of course, if I do so, I will get an error saying that
Procedure or function has too many arguments specified
What I want to do is to create the function such that when it executes a stored procedure, that stored procedure only takes the parameters that it needs and ignore the others. Is this possible?
Here is what I have so far:
try
{
using (SqlConnection con = new SqlConnection(consr))
{
SqlCommand cmd = new SqlCommand();
SqlDataReader reader;
cmd.CommandText = stp;
cmd.Parameters.Add(new SqlParameter("#proc1", cmb1.SelectedItem.ToString()));
cmd.Parameters.Add(new SqlParameter("#proc2", cmb2.SelectedItem.ToString()));
cmd.Parameters.Add(new SqlParameter("#proc3", cmb3.SelectedItem.ToString()));
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = con;
con.Open();
reader = cmd.ExecuteReader();
con.Close();
}
}
catch (SqlException exp)
{
throw new InvalidOperationException(exp.Message);
}
Here are two of the procedures:
ALTER PROCEDURE [dbo].[test1]
#proc1 varchar(20)
AS
Begin
select * from tab where name=#proc1
END
and
ALTER PROCEDURE [dbo].[test1]
#proc2 varchar(20)
AS
Begin
select * from tab where name=#proc2
END
I want to use the same function to execute both
You can set the params you don't want to use to null, then check for which values are available and respond accordingly
ALTER PROCEDURE [dbo].[test1]
#proc1 varchar(20) = null
#proc2 varchar(20) = null
#proc3 varchar(20) = null
AS
Begin
IF #proc1 IS NOT NULL BEGIN
select * from tab where name=#proc1
END
END
Make your function take two arguments, the name of the SP and a 2d array of SP argument names and their corresponding values. Then set up your sql command by iterating over the 2d array and adding the parameters in the loop.
If you need to return several result sets, see here: How do I return multiple result sets with SqlCommand? and modify the function and args so that they take an array of SP names and an array of 2d arrays, containing the SP arg names and values for each SP.
I think you should use this structure :
CREATE PROCEDURE MyProcName
#Parameter1 INT = 1,
#Parameter2 VARCHAR (100) = 'StringValue',
#Parameter3 VARCHAR (100) = NULL
AS
/* check for the NULL / default value (indicating nothing was passed */
if (#Parameter3 IS NULL)
BEGIN
/* whatever code you desire for a missing parameter*/
INSERT INTO ........
END
/* and use it in the query as so*/
SELECT *
FROM Table
WHERE Column = #Parameter
Can you please share the stored procedure code? I think you need to use if else or case statement in your function and call appropriate stored procedure with required parameters inside your function.

Parameter does not exist as a stored procedure parameter

ALTER PROCEDURE [dbo].[SelectCompletionNonCompletionCourseReport]
#LearnerName NVARCHAR(510) = NULL,
#ManagerId INT = NULL,
#CourseId INT = NULL,
#StartDateFrom SMALLDATETIME = NULL,
#StartDateTo SMALLDATETIME = NULL,
#TeamList XML = NULL,
#JobID NVARCHAR(max)=NULL,
#CourseStatus NVARCHAR(20)=NULL,
#ReportAdminID INT=0,
#ReportTeamList NVARCHAR(max)=NULL,
#RowsTotal int = 0,
#PageIndex int = 1,
#RowsPerPage int = 10
AS
BEGIN
DECLARE #TblCrieiria TABLE
(
id INT IDENTITY(1, 1),
areacode NVARCHAR(11),
regioncode NVARCHAR(11),
teamcode NVARCHAR(11)
)
IF #TeamList IS NULL
BEGIN
INSERT INTO #TblCrieiria VALUES(NULL,NULL,NULL)
END
BEGIN
This is the beginning of the procedure...
using (Database db = new Database(DScape.DAL.Config.ConfignPropertyName.DSCAPELMS_CONNECTION_STRING_NAME))
{
var cmd = new SqlCommand
{
CommandText = "SelectCompletionNonCompletionCourseReport",
CommandType = CommandType.StoredProcedure
};
cmd.Parameters.AddWithValue("#LearnerName", LearnerName);
cmd.Parameters.AddWithValue("#ManagerId", ManagerId);
cmd.Parameters.AddWithValue("#CourseId", CourseId);
cmd.Parameters.AddWithValue("#StartDateFrom", StartDateFrom);
cmd.Parameters.AddWithValue("#StartDateTo", StartDateTo);
cmd.Parameters.AddWithValue("#TeamList", TeamList);
cmd.Parameters.AddWithValue("#JobID", JobID);
cmd.Parameters.AddWithValue("#CourseStatus", CourseStatus);
cmd.Parameters.AddWithValue("#ReportAdminID", ReportAdminID);
cmd.Parameters.AddWithValue("#ReportTeamList", ReportTeamList);
cmd.Parameters.AddWithValue("#PageIndex", 1);
DataSet dsClient = db.GetDataSet(cmd);
if (dsClient.Tables.Count > 0)
return dsClient.Tables[0];
else
return null;
}
This is the method which communicates with the procedure, and it gaves me an error
Parameter does not exist as a stored procedure parameter/ function/procedure take too many arguments...
It's about #PageIndex parameter. Doesn't matter what is the value, we don't talk for values here but for parameter which is defined in the stored procedure but doesn't work?
And for the record, this problem did pop-up today w/o any code writing/modifying just appeared as I tried to do that report, when yesterday it was all good...I have a teammate which is next to me with absolute the same code both in sql and c# and it works just fine on his pc, but mine throws this errors, I'm trying to resolve this from 3 hours and I am completely out of answers , so please give me direction in which should I continue to resolve this .....................
and I say again, the problem is not from the connection to DB or type of the parameter or the value, the error is committed with the parameter itself - does not exist in the procedure, which is insane in my opinion.
Given that all parameters are optional, you are not required to explicitly provide any of them from your client code. Default values will be provided for you by SQL Server. The contract explictly states it in the stored procedure's signature.
An optional parameter is exactly that: optional. If you had provided the incorrect number of parameters, SQL Server would have returned a different error, indicating that the number of parameters was incorrect. This is not the case. Instead, you are seeing that you are asking for a parameter that is undefined, which indicates that the stored procedure signature you think you are calling does not match the stored procedure signature you are actually calling.
Verify that you are both connecting to the same database instance. If you are not, verify that the stored procedure is identical on both database instances.
parameter count doesnt match. check the params again.
You have to send parameters for rowstotal and rowsperpage as well because you have declared them at the top before "begin" clause.
If you do not want to send that params and they will be just constant, please declare them below as variable or constant, not a parameter.
i.e.
CREATE PROCEDURE DeleteById
#TableName sysname,
#Id int
AS
BEGIN
DECLARE #StrId AS VARCHAR(50)
SET #StrId = CONVERT(VARCHAR(50), #Id)
--any sp code here
END
Hope this helps.

Exception when calling a stored procedure

I have a SQL Server 2008 database and want to access a table from a C#-WCF via a stored procedure. The proc is a simple SELECT query that gets the row of a given id and fills the result into some outputparameters:
PROCEDURE [dbo].[get_stammInfo]
-- Add the parameters for the stored procedure here
#id int,
#strassenSchluessel int OUTPUT,
#hausNummer int OUTPUT,
#zusatz nvarchar(1) OUTPUT,
...
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
SELECT #strassenSchluessel = strassenSchluessel,
#hausNummer = hausNummer,
#zusatz = zusatz,
...
FROM gebaeudeStamm
WHERE id = #id
END
In my C#-Code, I create a commandobject, connect with the database and add the parameters to the commandobject.
When I call the ExecuteNonQuery, it throws the following exception
{"Die Prozedur oder Funktion 'getstammInfo' erwartet den '#id'-Parameter, der nicht bereitgestellt wurde."} which translate to something like "The procedure or function 'getstammInfo' expects the '
#id'-Parameter, which isn't provided"
Problem sounds clear, but actually I provided the id parameter. I can query it in the directwindow of VS2008:
_command.Parameters[0]
{#id}
base {System.Data.Common.DbParameter}: {#id}
CompareInfo: None
DbType: Int32
Direction: Input
IsNullable: false
LocaleId: 0
Offset: 0
ParameterName: "#id"
Precision: 0
Scale: 0
Size: 0
SourceColumn: ""
SourceColumnNullMapping: false
SourceVersion: Current
SqlDbType: Int
SqlValue: {7112}
TypeName: ""
UdtTypeName: ""
Value: 7112
XmlSchemaCollectionDatabase: ""
XmlSchemaCollectionName: ""
XmlSchemaCollectionOwningSchema: ""
As you can see, the id Parameter exists in the Parameterscollection and it has the same type like the parameter, the stored proc expects. I have no idea, what might be wrong, but it seems that the errormessage is wrong and some other error occured ...
Can anyone here hint me at what I should look to find the error?
Please show the code that you're using to call the procedure.
Your problem is that you put an # sign in the parameter name. When you add parameters to a SqlCommand, do not incldue the # sign.

Categories