I have created DataAccessLayer.cs file which helps me to make connection withe the database for insert records into the database and i have created store procedure.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Data.SqlClient;
public class DataAccessLayer
{
SqlConnection con = new SqlConnection("Connection String");
SqlCommand cmd;
public DataAccessLayer()
{
//
// TODO: Add constructor logic here
//
}
public int ExecuteProcedure(String procname, SqlParameter[]param)
{
cmd = new SqlCommand();
cmd.CommandText = procname;
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = con;
foreach (SqlParameter obj in param)
{
cmd.Parameters.Add(obj);
}
con.Open();
int i = cmd.ExecuteNonQuery();
con.Close();
return i;
}
}
Code for inserting record into data base using store procedure
SqlParameter[] param = new SqlParameter[]
{
new SqlParameter("#Name",txtFirstName.Text),
new SqlParameter("#DOB",txtDOB.Text),
new SqlParameter("#Address",txtAddress.Text),
new SqlParameter("#CN",ddlCountry.SelectedValue),
new SqlParameter("#SN",ddlState.SelectedValue),
new SqlParameter("CNN",ddlCity.SelectedValue),
new SqlParameter("#Mobile",txtMobile.Text),
new SqlParameter("#Email",txtEmail.Text),
new SqlParameter("#Pincode",txtPincode.Text),
new SqlParameter("#returnval",SqlDbType.Int)
};
int i = DAL.ExecuteProcedure("AddContactInfo", param);
if (i == 1)
{
lblError.Text = "Sucess";
}
else
{
lblError.Text = "Not Sucess";
}
Store Procedure for inserting records
ALTER proc [dbo].[AddContactInfo]
(
#Name varchar(50),
#DOB datetime,
#Address Varchar(max),
#Mobile varchar(15),
#Email varchar(50),
#CN int,
#SN int,
#CNN int,
#Pincode int,
#returnval int output
)
As
Begin
if exists(select Id from Contact_Info where Email=#Email)
begin
set #returnval=-2;
return #returnval;
end
else
begin
insert into Contact_Info(Name,DOB,Address,CountryName,StateName,CityName,Pincode,Mobile,Email,CreatedOn )
values(#Name,#DOB,#Address,#CN,#SN,#CNN,#Pincode,#Mobile,#Email,GETDATE())
if ##ERROR<>0
begin
set #returnval=-3;
return #returnval;
end
else
begin
set #returnval=1;
return #returnval;
end
end
End
But i am getting error which is "Procedure or function 'AddContactInfo' expects parameter '#returnval', which was not supplied."
You'll have to set your new SqlParameter("#returnval", SqlDbType.Int) to be an output parameter:
foreach (SqlParameter obj in param)
{
if (cmd.ParameterName == "#returnval")
{
cmd.Direction = ParameterDirection.Output
}
cmd.Parameters.Add(obj);
}
Of course, this expects all SP's to have the same #returnval when appropriate. It's better to set it when creating the list of parameters.
Related
I am trying to insert data into a SQL Server database by calling a stored procedure, but I am getting the error
Procedure or function 'sp_Lab_InsertBiologicalPersonnel' expects parameter '#IcNumber', which was not supplied
My stored procedure is called sp_Lab_InsertBiologicalPersonnel. I already check many time if there something missing, but still get same error, even make comparison with old code which is working. But for my code it say that error.
This is my C# code
public static PostApiResponse InsertBiologicalPersonel(Adapter ad, BiologicalPersonelInsert request, int creatorUserId)
{
var response = new PostApiResponse();
try
{
using (SqlCommand command = new SqlCommand("sp_Lab_InsertBiologicalPersonnel", ad.SQLConn, ad.SQLTran))
{
SqlParameter Param = new SqlParameter();
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter() { Value = request.biologicalId, ParameterName = "#biologicalId" });
command.Parameters.Add(new SqlParameter() { Value = request.IcNumber, ParameterName = "#IcNumber" });
command.Parameters.Add(new SqlParameter() { Value = request.Position, ParameterName = "#Position" });
command.Parameters.Add(new SqlParameter() { Value = creatorUserId, ParameterName = "#IdUserCreator" });
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
response.ResponseMessage = reader.GetString(0);
response.ReturnCode = reader.GetInt32(1);
response.Id = Convert.ToInt32(reader.GetValue(2));
}
reader.Close();
}
}
}
catch (Exception e)
{
throw e;
//string context = Common.ToStr(System.Web.HttpContext.Current);
//clsErrorLog.ErrorLog(context, e);
}
return response;
}
And this is my stored procedure:
ALTER PROCEDURE [dbo].[sp_Lab_InsertBiologicalPersonnel]
#biologicalId INT,
#IcNumber INT ,
#Position NVARCHAR(50),
#IdUserCreator INT
AS
BEGIN
SET NOCOUNT ON;
DECLARE #ReturnCode Int
DECLARE #ReturnMessage NVARCHAR(200)
DECLARE #Identity INT
INSERT INTO [dbo].[Lab_BiologicalPersonnel]
([Id]
--,[Name]
,[IcNumber]
,[Position]
,[IdUserCreator]
,[IsDeleted]
,[IsEnabled])
VALUES
(#biologicalId
--,#Name
,#IcNumber
,#Position
,#IdUserCreator
,0
,1)
IF ##ROWCOUNT = 0
BEGIN
SET #ReturnCode = 1
SET #ReturnMessage = 'Insert Fail'
SET #Identity = 0
END
ELSE
BEGIN
SET #ReturnCode = 0
SET #ReturnMessage = 'Insert Success'
SET #Identity = (SELECT SCOPE_IDENTITY())
END
SELECT #ReturnMessage, #ReturnCode, #Identity
END
Please help me explain in quite simple, I'm a newbie in programming.
I'm trying to pass list of objects and some other numbers and strings parameters to a SQL Server stored procedure using ado.net and execute it, and retrieve a value from an output parameter.
To capture the list of objects from the SQL Server stored procedure, I used a user-defined table type as shown here:
And this is the stored procedure:
ALTER PROCEDURE [dbo].[UpdateMailjetDetails]
#listCode VARCHAR(1000),
#listName VARCHAR(1000),
#mailjetListId BIGINT,
#mailjetListStatus INT,
#autoAsync BIT,
#contacts Contact READONLY,
#companyId INT,
#tblContactCompanyStatus INT,
#espListContactStatus INT,
#outputMessage VARCHAR(1000) OUT
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRANSACTION [Tran1]
BEGIN TRY
-- logic
--
--
SET #outputMessage = 'success';
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION [Tran1];
SELECT
'Error - Rollbacked -' AS CustomMessage,
ERROR_NUMBER() AS ErrorNumber,
ERROR_SEVERITY() AS ErrorSeverity,
ERROR_STATE() AS ErrorState,
ERROR_PROCEDURE() AS ErrorProcedure,
ERROR_LINE() AS ErrorLine,
ERROR_MESSAGE() AS ErrorMessage;
SET #outputMessage = 'error - ' + ERROR_MESSAGE();
END CATCH
END
This is the C# code which calls the stored procedure.
public string SaveAndPassToMailjetWindowsService(string listCode, string listName, long mailjetListId, MailjetListStatus mailjetListStatus, bool autoSync, List<Contact> contacts, int companyId, TblContactCompanyStatus tblContactCompanyStatus, EspListContactStatus espListContactStatus)
{
try
{
string result;
var conString = GetMailCoreConnectionString();
using (var conn = new SqlConnection(conString))
{
var command = new SqlCommand("UpdateMailjetDetails", conn)
{ CommandType = CommandType.StoredProcedure };
command.Parameters.Add(new SqlParameter("#listCode", listCode));
command.Parameters.Add(new SqlParameter("#listName", listName));
command.Parameters.Add(new SqlParameter("#mailjetListId", mailjetListId));
command.Parameters.Add(new SqlParameter("#mailjetListStatus", (int) mailjetListStatus));
command.Parameters.Add(new SqlParameter("#autoAsync", autoSync));
var contactsParam =
new SqlParameter("#contacts", SqlDbType.Structured)
{
TypeName = "dbo.Contact",
Value = GetSqlDataRecordsContactsList(contacts)
};
command.Parameters.Add(new SqlParameter("#contacts", contactsParam));
command.Parameters.Add(new SqlParameter("#companyId", companyId));
command.Parameters.Add(new SqlParameter("#tblContactCompanyStatus", (int) tblContactCompanyStatus));
command.Parameters.Add(new SqlParameter("#espListContactStatus", (int) espListContactStatus));
var outputParameter = new SqlParameter
{
ParameterName = "#outputMessage",
SqlDbType = SqlDbType.VarChar,
Direction = ParameterDirection.Output
};
command.Parameters.Add(outputParameter);
conn.Open();
command.ExecuteNonQuery(); // throws exception
result = outPutParameter.Value.ToString();
conn.Close();
}
return result;
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
And below is the C# method which converts the contacts list to a data table.
private List<SqlDataRecord> GetSqlDataRecordsContactsList(List<Contact> contacts)
{
try
{
List<SqlDataRecord> datatable = new List<SqlDataRecord>();
SqlMetaData[] sqlMetaData = new SqlMetaData[5];
sqlMetaData[0] = new SqlMetaData("Email", SqlDbType.NVarChar, 512);
sqlMetaData[1] = new SqlMetaData("Name", SqlDbType.NVarChar, 512);
sqlMetaData[2] = new SqlMetaData("TblContactId", SqlDbType.BigInt);
sqlMetaData[3] = new SqlMetaData("CompanyId", SqlDbType.Int);
sqlMetaData[4] = new SqlMetaData("TblContactCompanyId", SqlDbType.BigInt);
foreach (var contact in contacts)
{
SqlDataRecord row = new SqlDataRecord(sqlMetaData);
row.SetValues(contact.Email, contact.Name, contact.TblContactId ?? (object) DBNull.Value,
contact.CompanyId ?? (object) DBNull.Value,
contact.TblContactCompanyId ?? (object) DBNull.Value);
datatable.Add(row);
}
return datatable;
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
Now, when I run the code it does all the logic in stored procedure properly and completes all the changes I'm trying to do. I can see that data has been added via the stored procedure properly, but SaveAndPassToMailjetWindowsService methods
command.ExecuteNonQuery();
throws an exception in the C# side (even though the stored procedure executed its logic properly).
No mapping exists from object type System.Data.SqlClient.SqlParameter to a known managed provider native type.
Any guidance to fix this is much appreciated. Thanks.
Here you are adding the parameter as a value for a parameter:
var contactsParam =
new SqlParameter("#contacts", SqlDbType.Structured)
{
TypeName = "dbo.Contact",
Value = GetSqlDataRecordsContactsList(contacts)
};
command.Parameters.Add(new SqlParameter("#contacts", contactsParam)); //Problem is here
It should just be:
command.Parameters.Add(contactsParam);
I have this following stored procedure in sql:
CREATE PROCEDURE [dbo].[GetDocumentInfoById]
#DocumentID INT
AS
BEGIN
SET NOCOUNT ON;
SELECT
[DocumentID]
,[DocumentTitle]
,[DocumentVersion]
FROM
[dbo].[TblDocuments]
WHERE
[DocumentID]=#DocumentID
END
This is my code in C#:
public static DataSets.DocumentsDs GetDocumentInfoById(int documentId)
{
using (DbCommand loCmd = CreateDatabase.GetStoredProcCommand(GetDocumentInfoById))
{
using (DataSets.DocumentsDs loDocumentDs = new DataSets.DocumentsDs ())
{
CreateDatabase.AddInParameter(loCmd, "DocumentID", DbType.Int32, documentId);
CreateDatabase.LoadDataSet(loCmd, loDocumentDs , loDocumentDs.DocumentDT.TableName);
return loDocumentDs;
}
}
}
I tried this command in sql:
sp_help [GetDocumentInfoById]
and I got this in return:
Name: GetDocumentInfoById
Owner: dbo
Type: stored procedure
Parameter Name: #DocumentID
When I run my project I get this error: Procedure or function 'GetDocumentInfoById' has too many arguments.
What am I doing wrong? Please advise. Thanks
Update: Using DbCommad
public static DataSets.DocumentsDs GetDocumentInfoById(int documentId)
{
string con = ConfigurationSettings.AppSettings.GetValues("con").GetValue(0).ToString();
using (SqlConnection con = new SqlConnection(con))
{
using (SqlCommand cmd = new SqlCommand("GetDocumentInfoById", con))
{
using (DataSets.DocumentsDs loDocumentDs = new DataSets.DocumentsDs ())
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#DocumentID", DbType.Int32, documentId);
con.Open();
cmd.ExecuteNonQuery();
CreateDatabase.LoadDataSet(loCmd, loDocumentDs , loDocumentDs.DocumentDT.TableName);
return loDocumentDs;
}
}
}
}
Parameter names should have the # sufix:
This should be
CreateDatabase.AddInParameter(loCmd, "#DocumentID", DbType.Int32, documentId);
I have many stored procedure calls in my C# code, but only this one keeps failing. I'm running VS 2012 and SQL Server 2008 R2. My connection string is the same for all my stored procedures and I have the same permissions on all of them.
I get this error
Could not find stored procedure 'StP_Map_Preload #bldg, #linePos, #startD, #lineNo, #Pgrm, #apPos, #sessionID'.
System.Exception {System.Data.SqlClient.SqlException}
on this line:
SqlDataReader dr = cmd.ExecuteReader();:
I have tried creating a new stored procedure with the same code, setting permissions, but it fails too.
public ArrayList DetailPreload(string bldg, string linePos, DateTime startD, string lineNo, string Pgrm, int apPos, string sessionID)
{
string strSQL = "StP_Map_Preload #bldg, #linePos, #startD, #lineNo, #Pgrm, #apPos, #sessionID";
ArrayList list = new ArrayList();
using (SqlConnection conStr = new SqlConnection(connM))
{
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("#bldg", bldg);
cmd.Parameters.AddWithValue("#linePos", linePos);
cmd.Parameters.AddWithValue("#startD", startD);
cmd.Parameters.AddWithValue("#lineNo", lineNo);
cmd.Parameters.AddWithValue("#Pgrm", Pgrm);
cmd.Parameters.AddWithValue("#apPos", apPos);
cmd.Parameters.AddWithValue("#sessionID", sessionID);
cmd.CommandText = strSQL;
cmd.Connection = conStr;
conStr.Open();
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
list.Add(new
{
company = dr["Company"],
Pgrm = dr["Pgrm"],
lineNum = dr["lineNum"],
lineStation = dr["lineStation"],
jobCount = dr["Job"],
item = dr["Item"],
qty = dr["Qty"],
partQty = dr["partQty"],
invCnt = dr["invCnt"],
runID = dr["runID"]
});
}
conStr.Close();
return list;
}
}
}
My stored procedure is in SQL Server and I can execute it in SQL Server
/*
StP_Map_Preload 'AA-12', '7', '09/19/2014', '', '247', 7, 'val2gxfh5ihoqy4tshzl4tp3'
*/
ALTER proc [dbo].[StP_Map_Preload]
#Bldg varchar(10),
#linePos varchar(5),
#startD date,
#LineNo varchar(5),
#Pgrm varchar(5),
#apPos int,
#sessionID varchar(50)
AS
BEGIN
declare #sql varchar(Max), #PST varchar(20),
#SI1 varchar(5), #SI2 varchar(5), #SI3 varchar(5),
#hasAP bit, #CCLen varchar,
#Co varchar(5), #CCs varchar(25), #lsGrp varchar(max)...
Change your line to
string strSQL = "StP_Map_Preload";
There is no need to list the parameters in the string that names the stored procedure.
I'm trying to get the ID of the row affected in "real time". I could check it for the parameters used or the last row, but I want to do it with the least delay possible, so that there isn't multiple users mixing information in the tables.
Tried so far:
public int setFileInfo(string fileName, int filePrivacy, string filePassword, string fileDesc, string fileOwner)
{
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["bitRain"].ConnectionString))
{
SqlCommand cmd = new SqlCommand("dbo.Upload", conn);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
if(!String.IsNullOrEmpty(filePassword))
{
filePassword = FormsAuthentication.HashPasswordForStoringInConfigFile(filePassword, "MD5");
}
try
{
conn.Open();
cmd.Parameters.Add("#fileName", fileName);
cmd.Parameters.Add("#filePrivacy", filePrivacy);
cmd.Parameters.Add("#filePassword", filePassword);
cmd.Parameters.Add("#fileDescription", fileDesc);
cmd.Parameters.Add("#fileOwner", fileOwner);
int fileID = (int)cmd.ExecuteScalar();
return fileID;
}
catch (Exception ex)
{ }
finally
{
conn.Close();
}
return -1;
}
}
Stored Procedure:
CREATE PROCEDURE [dbo].[Upload]
#fileName nvarchar(20),
#filePrivacy int,
#filePassword nvarchar(50),
#fileDescription nvarchar(200),
#fileOwner nvarchar(14)
AS
INSERT INTO Files ([FileName], FilePrivacy, FilePassword, FileDescription, FileOwner)
VALUES (#fileName, #filePrivacy, #filePassword, #fileDescription, #fileOwner)
RETURN 0
I need some OUTPUT parameter, but I don't know how to use it and msdn examples aren't clear enough for me.
Stored Procedure:
CREATE PROCEDURE [dbo].[Upload]
#fileName nvarchar(20),
#filePrivacy int,
#filePassword nvarchar(50),
#fileDescription nvarchar(200),
#fileOwner nvarchar(14),
#id int out
AS
INSERT INTO Files ([FileName], FilePrivacy, FilePassword, FileDescription, FileOwner)
VALUES (#fileName, #filePrivacy, #filePassword, #fileDescription, #fileOwner)
set #id = SCOPE_IDENTITY()
END
In cs add
cmd.Parameters["#id"].Direction = ParameterDirection.Output;
try to use SCOPE_IDENTITY function