i have a sql procedure, but as access accepts only single statement, i'd like to control the differents statement through the code side using C# with Dbcommand...in order to find the equivalent. here is the sql procedure, i'm gonna show you the C# code but i got an error.
CREATE PROCEDURE CreateOrders
(#cartId char(36))
As
/*insert a new record into Commande étape 1 :"PasserCommande1"*/
DECLARE #CmdID int
INSERT INTO Commande DEFAULT VALUES
/*save the new commande id*/
SET #CmdID = ##IDENTITY
/*Add the order detail to DetailsCommande(orderdetails table) étape 2 :"PasserCommande2"*/
INSERT INTO DetailsCommande ( CmdID, ProduitID, ProduitTitre, Quantite, CoutUnitaire )
SELECT [#CmdID], livres.NumLivre, livres.titre, ShoppingCart.Quantite, livres.prix
FROM livres INNER JOIN ShoppingCart ON livres.NumLivre = ShoppingCart.ProduitID
WHERE ShoppingCart.CartID=[#CartID]
/*Clear the shopping Cart étape 3 :"PasserCommande3"*/
DELETE FROM ShoppingCart
WHERE CartID = #CartID
/*return the order id étape 4:"PasserCommande4"*/
SELECT #CmdID;
so i separated the procedure in 4 differents statements, so that i can call them one by one with c#, but i got a error when retreiving the ##identity value from the Commande table to put it in the DetailsCommande. the CmdID has an identity property in the table Commande. here is what i'm trying to do in C#:
public static string PasserCommande()
{
//étape 1
//on obtient l'objet configuré DbCommande
DbCommand m_cmd = LibAccesGenerique.CreerCmd();
//on définit la procédure stockée
m_cmd.CommandText = "PasserCommande_1";
LibAccesGenerique.ExecuteNonQuery(m_cmd);
//étape 2
DbCommand m_cmd1 = LibAccesGenerique.CreerCmd();
m_cmd1.CommandText = "PasserCommande_2";
//on crée un nouveau paramètre
DbParameter m_param = m_cmd1.CreateParameter();
m_param.ParameterName = "#CmdID";
m_param.Value = "##IDENTITY";
m_param.DbType = DbType.Int32;
m_cmd1.Parameters.Add(m_param);
//2ème param
m_param = m_cmd1.CreateParameter();
m_param.ParameterName = "#CartID";
m_param.Value = ShoppingCartId;
m_param.DbType = DbType.String;
m_param.Size = 36;
m_cmd1.Parameters.Add(m_param);
LibAccesGenerique.ExecuteNonQuery(m_cmd1);
//étape3
DbCommand m_cmd2 = LibAccesGenerique.CreerCmd();
m_cmd2.CommandText = "PasserCommande3";
DbParameter m_param2 = m_cmd2.CreateParameter();
m_param2 = m_cmd1.CreateParameter();
m_param2.ParameterName = "#CartID";
m_param2.Value = ShoppingCartId;
m_param2.DbType = DbType.String;
m_param2.Size = 36;
m_cmd2.Parameters.Add(m_param);
LibAccesGenerique.ExecuteNonQuery(m_cmd2);
//étape 4
DbCommand m_cmd3 = LibAccesGenerique.CreerCmd();
m_cmd3.CommandText = "PasserCommande_4";
//on créer un nouveau paramètre
DbParameter m_param1 = m_cmd3.CreateParameter();
m_param1.ParameterName = "#CmdID";
m_param1.Value = "##IDENTITY";
//m_param1.Direction = ParameterDirection.InputOutput;
m_param1.DbType = DbType.Int32;
m_cmd3.Parameters.Add(m_param1);
return LibAccesGenerique.ExecuteScalar(m_cmd3);
}
the error comes at etape 2 as i put in my comments. the exception says that the format of the input string is incorrect... i'm sure it comes when i try to assign the ##identity to #cmdID paramater. i don't know if there is a another way to code it.
##IDENTITY works with access, but it's a bit ordinary. Try sending it as a straight command
SELECT ##IDENTITY;
assigning the results to a variable using ExecuteScalar, then assigning that variable to the parameter instead. Also bear in mind that with access, ##IDENTITY only works with a normal AutoNumber, not a ReplicationID (GUID).
You should return ##Identity as an 'Output' parameter. Add an output parameter to your stored procedure and add a the same parameter to your C# code with Direction = ParameterDirection.Output.
See this answer for a great example: Using stored procedure output parameters in C#
Also, as a best practice, consider changing ##Identity to Scope_Identity().
Related
I've read many posts and think I understand the concepts, but my small array of ints fails to pass from a C#/EF module to a SQL Server stored proc. Hoping other eyes can spot the problem.
I'm using EF6, 4.5 .Net Framework, SQL Server 2014
In the database I've created these types/procs:
CREATE TYPE [dbo].[IntsTTV] AS TABLE(
[Id] [int] NOT NULL
)
Note that a table named 'Person' exists with columns 'Id' (int) and 'LastName' (nvarchar), and has data.
CREATE PROCEDURE [dbo].[GetUsers]
#UserIds dbo.IntsTTV READONLY
AS
BEGIN
SELECT p.LastName
FROM [dbo].[Person] p
INNER JOIN #UserIds ids On p.Id = ids.Id;
END
// C# code
SqlMetaData[] columns = new SqlMetaData[1];
columns[0] = new SqlMetaData("Id", SqlDbType.Int);
SqlDataRecord row = new SqlDataRecord(columns);
row.SetInt32(0, 1); // Id of '1' is valid for the Person table
SqlDataRecord[] table = new SqlDataRecord[1];
table[0] = row;
SqlParameter parameter = new SqlParameter();
parameter.SqlDbType = SqlDbType.Structured;
parameter.ParameterName = "#UserIds";
parameter.TypeName = "dbo.IntsTTV";
parameter.Direction = ParameterDirection.Input;
parameter.Value = table;
SqlParameter[] parameters = new SqlParameter[1];
parameters[0] = parameter;
var res = _db.Database.SqlQuery<string>("GetUsers", parameters).ToList();
The code does successfully call the proc, and if I hard code the proc to simply return a select of LastName's then the C# code does receive that. This tells me what is working.
If I call the proc from other T-SQL code, passing in a prepared table-valued parameter (IntsTTV) of ints, it works.
In the proc, if I select count of rows of the passed parameter table I get zero when calling from the C# code, but I get a correct count when calling from T-SQL code.
What am I missing, please?
This is how I call stored procedure with table valued parameter. The main difference being that I use a DataTable parameter.
I remember having issues with parameter name bindings, but I don't remeber exactly what they were. This explains the change I made in the syntax of the procedure call. I know this one should be working.
var dataTable = new DataTable();
dataTable.TableName = "dbo.IntsTTV";
dataTable.Columns.Add("Id", typeof(int));
dataTable.Rows.Add(1); // Id of '1' is valid for the Person table
SqlParameter parameter = new SqlParameter("UserIds", SqlDbType.Structured);
parameter.TypeName = dataTable.TableName;
parameter.Value = dataTable;
var res = _db.Database.SqlQuery<string>("EXEC GetUsers #UserIds", parameter).ToList();
I know this has been answered by found a different way that might help someone else out there
STRING_SPLIT
declare #intArray nvarchar(1000)
set #intArray = '1,2,3,4,5'
select value from STRING_SPLIT(#intArray , ',')
This will return a new table with the numbers in your #intArray
Then you just need to use it as a normal table
select * from myMainTable where Id in (select value from STRING_SPLIT(#intArray , ','))
That worked! For the sake of others I'll post the precise code here, which I had to tweak slightly.
var dataTable = new DataTable();
dataTable.TableName = "dbo.IntsTTV";
dataTable.Columns.Add("Id", typeof(int));
dataTable.Rows.Add(1); // Id of '1' is valid for the Person table
SqlParameter parameter = new SqlParameter("UserIds", SqlDbType.Structured);
parameter.TypeName = "dbo.IntsTTV";
parameter.Value = dataTable;
var res = _db.Database.SqlQuery<string>("EXEC dbo.GetUsers #UserIds", parameter).ToList();
I'm currently trying to try catch the insert SQL query from my simple C# application, but when i'm trying to insert the data into database with user id which is added into userIDList parameter, the error came out saying that
The incoming request has too many parameters. The server supports a
maximum of 2100 parameters.
The userIDList sometimes will contains like 60 arrays above then the error will popped out.
My SQL CommandText will contain of
"SELECT * FROM TIME_ATTENDANCE_REPORT WHERE TRXDATETIME = #Date AND USERID IN (001,002,003,004,....)
So i think if more then certain number then the error popped out
Here are my sample code :
List<string> userIDList = new List<string>();
using (SqlCommand sqlDBComm = new SqlCommand())
{
openConnection();
SqlDataReader sqlDBReader;
sqlDBReader = null;
sqlDBComm.CommandText = "SELECT * FROM TIME_ATTENDANCE_REPORT WHERE TRXDATETIME = #Date AND USERID IN (" + string.Join(",", userIDList) + ") ORDER BY USERID ASC ";
sqlDBComm.Parameters.Add("#Date", SqlDbType.DateTime);
sqlDBComm.Parameters["#Date"].Value = GetDateFrom;
sqlDBComm.Connection = sqlDB;
sqlDBComm.CommandType = CommandType.Text;
try
{
sqlDBReader = sqlDBComm.ExecuteReader();
t.Load(sqlDBReader);
sqlDBReader.Close();
if (t.Rows.Count > 0)
{
status = "Update";
}
else
{
status = "Insert";
}
}
catch (Exception errMsg)
{
MessageBox.Show("Error Code: " + errMsg.ToString());
}
finally
{
sqlDBReader.Close();
closeConnection();
}
}
Any other solution can resolve this?
Thanks
There are many ways to solve this problem.
Instead of sending a list of IDs as seperate parameters, you can send a single #IDList parameter as a single comma separated string and let it parsed into IDs at the server side. Here is a function that I use for this (borrowed and modified from Jeff Moden's code):
CREATE FUNCTION [dbo].[iSplitter] (#Parameter VARCHAR(MAX))
RETURNS #splitResult TABLE (number INT, [value] INT)
AS
BEGIN
SET #Parameter = ','+#Parameter +',';
WITH cteTally AS
(
SELECT TOP (LEN(#Parameter))
ROW_NUMBER() OVER (ORDER BY t1.Object_ID) AS N
FROM Master.sys.All_Columns t1
CROSS JOIN Master.sys.All_Columns t2
)
INSERT #splitResult
SELECT ROW_NUMBER() OVER (ORDER BY N) AS Number,
SUBSTRING(#Parameter,N+1,CHARINDEX(',',#Parameter,N+1)-N-1) AS [Value]
FROM cteTally
WHERE N < LEN(#Parameter) AND SUBSTRING(#Parameter,N,1) = ','
RETURN
END
With this function created once, I do it like:
sqlDBComm.CommandText = #"SELECT * FROM TIME_ATTENDANCE_REPORT tar
inner Join dbo.iSplitter(#UserIdList) ul on tar.USERID = ul.[value]
WHERE TRXDATETIME = #Date
ORDER BY USERID ASC ";
sqlDBComm.Parameters.AddWithValue("#UserIdList",string.Join(",", userIDList));
This works very well for 5-6K integer ids but times out if used with 20-30K or more IDs. Then I created another alternative as a CLR procedure, and that one parses the list server side in less than a second. But I think this one is sufficient for your needs.
Another way is to send the IDs as an XML parameter and parse server side again.
Yet another way is to send a table parameter.
PS: Here is a link that shows sample code for other ways. The site is in Turkish but the codes are crystal clear in C#, separate per approach.
EDIT: XML sample using Northwind Orders table:
void Main()
{
int[] IDList = { 10265,10266,10267,10268,10269,10270,10271,10272,10273,10274,10275, 10320, 10400 };
var idsAsXML = new XElement("IDS",
from i in IDList
select new XElement("Row", new XAttribute("Id", i)));
string sql = #"
DECLARE #hDoc int;
DECLARE #tbl TABLE (Id int);
exec sp_xml_preparedocument #hDoc OUTPUT, #XML;
INSERT #tbl
SELECT *
FROM OPENXML(#hDoc, #Nodename, 1) WITH (Id int);
EXEC sp_xml_removedocument #hDoc;
select * from Orders o
where exists (select * from #tbl t where t.Id = o.OrderId) ";
DataTable tbl = new DataTable();
using (SqlConnection con = new SqlConnection(#"server=.\SQLExpress;Trusted_Connection=yes;Database=Northwind"))
{
SqlCommand cmd = new SqlCommand(sql, con);
cmd.Parameters.AddWithValue("#XML", idsAsXML.ToString());
cmd.Parameters.AddWithValue("#NodeName", "/IDS/Row");
con.Open();
tbl.Load(cmd.ExecuteReader());
con.Close();
}
//tbl.Dump(); // linqPad luxury
}
You can create a Table-Valued-Parameter and pass it as a parameter. It requires you to create a new type in your database, and will enable you to pass an array to the query and let the database treat it as a table. If this is something you do a lot, it could come in handy.
I no longer have access to the project where I implemented this but everything is available in the blog post. The code below is not tested, but I hope it can get you in the right direction.
1. Create a new type in your database:
CREATE TYPE integer_list_tbltype AS TABLE (n int NOT NULL PRIMARY KEY)
2. Pass it as parameter:
sqlDBComm.Parameters.Add("#userIds", SqlDbType.Structured)
sqlDBComm.Parameters["#userIds"].Direction = ParameterDirection.Input
sqlDBComm.Parameters["#userIds"].TypeName = "integer_list_tbltype"
sqlDBComm.Parameters["#userIds"].Value = CreateDataTable(userIDList)
3. Method for creating the parameter:
private static DataTable CreateDataTable(IEnumerable<int> ids) {
DataTable table = new DataTable();
table.Columns.Add("n", typeof(int));
foreach (int id in ids) {
table.Rows.Add(id);
}
return table;
}
4. Use it in your SQL:
... AND USERID IN (SELECT n FROM #userIds)
CreateDataTable from here:
How to pass table value parameters to stored procedure from .net code
Rest from here:
http://www.sommarskog.se/arrays-in-sql-2008.html#introduction
Sorry if someone has already given an answer to this, I have been browsing the site and trying tips and bits of code for hours, to no avail.
I have a stored procedure which basically retrieves the id of an element, if this element exists, and zero if it doesn't.
Here we go:
PROCEDURE [dbo].[ChecksProductExistence]
#Product_Name varchar(50),
#Return_Value Int output
AS
BEGIN
IF EXISTS (SELECT prod.ProductID
FROM dbo.Products prod
WHERE prod.ProductName = #Product_Name)
SET #Return_Value = 1;
ELSE
SET #Return_Value = 0;
END
Okay, so far so good. Execute that in my database, and it works like a charm... not that it's such complex code.
Then, in Visual Studio, I coded the following:
private static bool checkExistingProduct(ShoppingListContext ctx, Product product)
{
var cmd = ctx.Database.Connection.CreateCommand();
cmd.CommandText = "[dbo].[ChecksProductExistence]";
ctx.Database.Connection.Open();
int bla = 0;
SqlParameter inParameter = new SqlParameter();
inParameter.ParameterName = "#Product_Name";
inParameter.SqlDbType = SqlDbType.NVarChar;
inParameter.Direction = ParameterDirection.Input;
inParameter.Value = product.ProductName;
SqlParameter outParameter = new SqlParameter();
outParameter.ParameterName = "#Return_Value";
outParameter.SqlDbType = SqlDbType.Int;
outParameter.Direction = ParameterDirection.Output;
cmd.Parameters.Add(inParameter);
cmd.Parameters.Add(outParameter);
bla = cmd.ExecuteNonQuery();
Console.WriteLine(outParameter.Value);
Console.ReadLine();
if ((int)outParameter.Value == 1) return true; else return false;
}
As you can see... simple enough. I create a command, add parameters, execute it, try some decision making on the output.
But... I get an error on the
cmd.ExecuteNonQuery();
line. I have changed it to ExecuteScalar, for example, but still no luck. I have executed it without the "bla = ...", and still the same.
The error I get is
An unhandled exception of type 'System.Data.SqlClient.SqlException' occurred in System.Data.dll
Additional information: Procedure or function 'ChecksProductExistence' expects parameter '#Product_Name', which was not supplied.
But then again, not only can you see clearly in the code that I AM IN FACT SUPPLYING IT, but also on the debug session I can explore the cmd object and browse the parameters, and I can see that IT IS THERE, and the values are correct...
So what else can I do?? Am I making some silly mistake I can't see...?
As stated in the documentation for SqlCommand.CommandType you have to set it to CommandType.StoredProcedure and set the CommandText to the name of the stored procedure. It defaults to CommandType.Text where you have to include the named parameters in the text of the query.
When you set the CommandType property to StoredProcedure, you should
set the CommandText property to the name of the stored procedure. The
command executes this stored procedure when you call one of the
Execute methods.
The Microsoft .NET Framework Data Provider for SQL
Server does not support the question mark (?) placeholder for passing
parameters to a SQL Statement or a stored procedure called with a
CommandType of Text. In this case, named parameters must be used. For
example:
SELECT * FROM Customers WHERE CustomerID = #CustomerID
So, just add the following
cmd.CommandType = CommandType.StoredProcedure;
somewhere before executing it.
I am trying to INSERT my data into two tables Services and Service-line
Explaining my stored procedure:
It checks for existing ID in the Form
If not found it creates a new record in the Services table the info in the Form, then gets the ID using scope_identity and uses the ID for the Service-Line table.
Also the ID is returned to the Form and stays tre.
Later while inserting second record in Service-Line, the stored procedure checks for existing ID; if found, this time, it takes the ID from the Form and uses it in the Service-Line
This Is my stored procedure
please bear with me, as I am working in this code and testing, a lot of line are commented out
ALTER PROCEDURE [dbo].[InsertServiceServiceLine] (
--Services Entry
--FOR IF CONDITION ---CHECK THE DEFAULT VALUE IN THE FORM on SID
#ExistingSID int,
--SEELCT PARAMETES DEF VALUES
#ComboBoxSelectedBike varchar(100),
-- INPUT PARAMETERES FOR NEW RECORD
#CID int,
#Status bit = 1,
#CurrentMeter int,
#Labor decimal(20,0),
#GrandTotal decimal(20,0) = ISNULL,
--#NextService datetime,
--Service Line
#Spare nvarchar(500),
#Quantity int,
#Uprice decimal(20,2),
#Subtotal decimal(20,2)
)
AS
BEGIN
IF (#ExistingSID <= 0)
BEGIN
SET NOCOUNT ON;
DECLARE #BikeID int
SELECT #BikeID = (SELECT BikeID FROM TblBikeNames WHERE BikeName = #ComboBoxSelectedBike)
INSERT INTO [AutoDB_Sample].[dbo].[TblServices]
(CID,BikeID,Status,CurrentMeter,Labor,DateOfService)
VALUES
(#CID,#BikeID,#Status,#CurrentMeter,#Labor,GETDATE())
DECLARE #SID int
SET #SID = SCOPE_IDENTITY()
INSERT INTO [AutoDB_Sample].[dbo].[TblServiceLine]
(SID,Spare,Quantity,Uprice,Subtotal,DateCreated)
VALUES
(#SID,#Spare,#Quantity,#Uprice,#Subtotal,GETDATE())
RETURN #SID
END
ELSE
BEGIN
INSERT INTO [AutoDB_Sample].[dbo].[TblServiceLine]
(SID,Spare,Quantity,Uprice,Subtotal,DateCreated)
VALUES
(#ExistingSID,#Spare,#Quantity,#Uprice,#Subtotal,GETDATE())
END
END
It gives me an error when I use this stored procedure in a C# Windows Forms
Procedure or Function has too many Arguments
Here's a screenshot of the error
I thought that Putting my login in SP would be great and improve the performance of my application. But now am stuck.
This is my C# Code
public void AddItemIntoServices_ServiceLine()
{
ConnectionStringSettings consetting = ConfigurationManager.ConnectionStrings["AutoDB"];
String ConnectionString = consetting.ConnectionString;
SqlConnection con = new SqlConnection(ConnectionString);
try
{
con.Open(); // open the connection
// Specify the name of the Stored Procedure you will call
String SP_Name = "InsertServiceServiceLine";
// Create the SQL Command object and specify that this is a SP.
SqlCommand cmd = new SqlCommand(SP_Name, con);
cmd.CommandType = CommandType.StoredProcedure;
// Specify values for the input parameters of our Stored Procedure
// Parameters MUST be named the same as the parameters defined in the Stored Procedure.
//~~ If Condition Parameter ****************************************************************************~~//
int exitstingSID;
if (int.TryParse(LblSID_Data.Text, out exitstingSID)) ;
SqlParameter ExistingSID = new SqlParameter("#ExistingSID", exitstingSID);
ExistingSID.Direction = ParameterDirection.Input;
ExistingSID.DbType = DbType.Int16;
cmd.Parameters.Add(ExistingSID);
//Parameter to select Bike ID from Selected Bike Name
SqlParameter ParamBikeID = new SqlParameter("#ComboBoxSelectedBike", ComboBx_BikeNames.Text);
ParamBikeID.Direction = ParameterDirection.Input;
ParamBikeID.DbType = DbType.String;
cmd.Parameters.Add(ParamBikeID);
//~~ Customer Info ************************************************************************************~~//
//CID Convertion
int P_CID;
if (int.TryParse(LblCID_Data.Text, out P_CID)) ;
cmd.Parameters.AddWithValue("#CID", P_CID);
cmd.Parameters.AddWithValue("#Cname", this.TxtBx_CustomerName.Text);
cmd.Parameters.AddWithValue("#Vnum", this.TxtBx_VehicleNumber.Text);
//~~ Service Info ************************************************************************************~~//
//Labor Convertion
int Laborint;
if (int.TryParse(TxtBxLabor.Text, out Laborint)) ;
SqlParameter ParamLabor = new SqlParameter("#Labor", Laborint);
ParamLabor.Direction = ParameterDirection.Input;
ParamLabor.DbType = DbType.Int16;
cmd.Parameters.Add(ParamLabor);
//CurrentMeterConversion
int currentMeterint;
if (int.TryParse(TxtBx_CurrentMeter.Text, out currentMeterint)) ;
SqlParameter ParamCurrentMeter = new SqlParameter("#CurrentMeter", currentMeterint);
ParamCurrentMeter.Direction = ParameterDirection.Input;
ParamCurrentMeter.DbType = DbType.Int16;
cmd.Parameters.Add(ParamCurrentMeter);
//Return Value
SqlParameter ParamReturn = new SqlParameter("#SID", SqlDbType.Int);
ParamReturn.Direction = ParameterDirection.Output;
ParamReturn.DbType = DbType.Int16;
cmd.Parameters.Add(ParamReturn);
//~~ Service Info ************************************************************************************~~//
//Converstions
Decimal UP, ST;
if (Decimal.TryParse(TxtBx_UnitPrice.Text, out UP)) ;
if (Decimal.TryParse(TxtBxTotal.Text, out ST)) ;
//SpareName
cmd.Parameters.AddWithValue("#Spare", ComboBx_SparesName.Text);
//Quantity
cmd.Parameters.AddWithValue("#Qty", NumericBx_Quantity.Value);
//Unit Price
SqlParameter ParamUp = new SqlParameter("#Uprice", UP);
ParamUp.Direction = ParameterDirection.Input;
ParamUp.DbType = DbType.Decimal;
cmd.Parameters.Add(ParamUp);
//Total
SqlParameter ParamTot = new SqlParameter("Subtotal", ST);
ParamTot.Direction = ParameterDirection.Input;
ParamTot.DbType = DbType.Decimal;
cmd.Parameters.Add(ParamTot);
cmd.ExecuteNonQuery();
String _returnedSID = cmd.Parameters["#SID"].Value.ToString();
LblSID_Data.Text = _returnedSID;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
con.Close();
clear();
ToolStripLable_Status.Text = "New Service Record Created";
}
}
The list of parameters passed through the command collection should match exactly what the stored procedure expects by name, type and direction.
Your list of parameters included in the command collection doesn't match with the parameters required by the stored procedure and thus you get the error.
At first sight I could say:
cmd.Parameters.AddWithValue("#Cname", this.TxtBx_CustomerName.Text);
cmd.Parameters.AddWithValue("#Vnum", this.TxtBx_VehicleNumber.Text);
SqlParameter ParamReturn = new SqlParameter("#SID", SqlDbType.Int);
are parameters added to the command collection but are not present in the stored procedure list of parameters.
On the contrary we have the parameters #status bit and #GrandTotal decimal(20,0) = ISNULL, required by the stored procedure but not present in the list. (By The way, the default syntax for a NULL parameter is #GrandTotal decimal(20,0) = NULL
Finally the stored procedure names a parameter #Quantity but you add a parameter named #Qty.
Now there is also the problem of the parameter types that should match otherwise you risk an automatic conversion at best or a error message stating about type mismatches.
You have numerous parameter of type int but you pass parameters of type Int16 while the correct type is Int32. And there is also a more clear error in the type of the parameter #Labor that is expected to be a decimal by the sp but you add it as an integer (16)
You have 12 parameters in the stored procedure definition (if I counted correctly), however, your code may have more or less than that. There is either one too many parameters defined within the code, or the stored procedure expects a 13th parameter. I think the error mentions the former, but I sometimes get them confused.
Anyway that error is always due to a mismatch in the number of parameters, and make sure the direction (input/output) is setup correctly, and everything is typed OK.
I have a stored procedure called pat_selectPatientById and that stored procedure returns a true or false using ISNULL(#isEqual, 0) as IsProviderSameAsPCP.
I am trying to call this stored procedure using a C# method by calling Application.WebService.ExecuteQuery("pat_selectPatientById"). But I'm not having any luck - can someone point me in the right direction?
Thanks a lot guys
Code:
declare #isEqual bit =
(select
top 1 1 as IsEqual
from
Patient p
inner join
[Resource] r on p.ProviderId = r.ResourceId
where
PatientId = #PatientId
and p.PrimaryCareProviderId = r.RefPhysId)
You need to return the value from your stored procedure.
SELECT #isEqual
Aside that you need a SqlConnection object and a SqlCommand object to invoke the stored procedure.
conn = new SqlConnection(connectionString);
conn.Open();
SqlCommand cmd = new SqlCommand("IsProviderSameAsPCP", conn);
cmd.CommandType = CommandType.StoredProcedure;
rdr = cmd.ExecuteReader();
You can then use the rdr object to loop through the result set.
You can find your connection string at:
http://www.connectionstrings.com/
I.e. for SQL Server 2008:
string connectionString = "Server=myServerAddress;Database=myDataBase;Trusted_Connection=True;";
You need to return the value in a select. Next line in your proc needs to be
select #isEqual
ie..
declare #isEqual bit =
(select
top 1 1 as IsEqual
from
Patient p inner join [Resource] r
on p.ProviderId = r.ResourceId
where
PatientId = #PatientId
and p.PrimaryCareProviderId = r.RefPhysId)
select #isEqual
ExecuteScalar is the command in C# you are looking for. You could also use an output parameter on your stored proc if you have multiple values and don't want to return a table output.