I am stuck in a problem. i am getting error "Procedure or function 'SP_RPT_User' expects parameter '#deptName', which was not supplied." in c# application while parameter is provided. even i copied and replaced the name. still no success.
public DataTable SP_RPT_User(int loggedid, String deptName, String OfficeName, String empType)
{
int updatedrows = 0;
DataTable table = new DataTable();
try
{
cCommand = new System.Data.SqlClient.SqlCommand("SP_RPT_User", connection);
cCommand.CommandType = CommandType.StoredProcedure;
cCommand.Parameters.Add("#loggedId", SqlDbType.Int).Value = loggedid;
cCommand.Parameters.Add("#deptName", SqlDbType.NVarChar, 200).Value = deptName;
cCommand.Parameters.Add("#OfficeName", SqlDbType.VarChar, 150).Value = OfficeName;
cCommand.Parameters.Add("#empType", SqlDbType.VarChar, 150).Value = empType;
cCommand.CommandTimeout = 90000;
connection.Open();
updatedrows = cCommand.ExecuteNonQuery();
using (var da = new SqlDataAdapter(cCommand))
{
cCommand.CommandType = CommandType.StoredProcedure;
da.Fill(table);
}
}
catch (Exception Ex)
{
connection.Close();
// return -100;
}
finally
{
connection.Close();
}
return table;
}
Stored Procedure
ALTER PROCEDURE [dbo].[SP_RPT_User]
-- Add the parameters for the stored procedure here
#loggedId int,
#deptName NVarChar(200),
#OfficeName varchar(150),
#empType varchar(150)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
declare #sql nvarchar(max);
set #sql ='SELECT ...'; // here is one query
if(#deptName != '')
set #sql = #sql + ' and dbo.TB_Department.name like ''%'+#deptName+'%''';
Declare #params nvarchar(500)
SELECT #params ='#loggedId int,'+
'#deptName NVarChar(200),'+
'#OfficeName varchar(150),'+
'#empType varchar(150)'
exec sp_executesql #sql, #params,#loggedId,#deptName,#OfficeName,#empType;
END
Can anyone help. thanks in advance.
i am using sql server 2014 and vs2015.
The educated guess I have is that deptName value in C# is null while you execute the query. In such case you should pass DBNull.Value to have null as parameter value:
var param = cCommand.Parameters.Add("#deptName", SqlDbType.NVarChar, 200);
param.Value = deptName ?? DBNull.Value;
From your procedure I see that you compare with empty string so use ?? string.Empty to satisfy that condition.
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 am trying to load output parameters from my SQL stored procedure.
USE [EdiMon_Beta]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[GetClients]
-- Add the parameters for the stored procedure here
#sender nvarchar(max),
#subSender nvarchar(max),
#receiver nvarchar(max),
#subReceiver nvarchar(max),
#msgTypeID int,
#ErrorMsg nvarchar(max) = null OUTPUT,
#processId int = 0 OUTPUT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE
#senderId int,
#subSenderId int,
#receiverId int,
#subReceiverId int
SELECT
#senderId = ID
FROM [dbo].[Party_Client]
WHERE
[Number] LIKE #sender
IF(#senderId IS NULL)
BEGIN
SET #ErrorMsg = 'Sender does not exist'
RETURN ;
END
SELECT
#subSenderId = ID
FROM [dbo].[Party_Client]
WHERE
[Number] LIKE #subSender
AND ParentId = #senderId
AND IsSubClient = 1
IF(#subSenderId IS NULL)
BEGIN
SET #ErrorMsg = 'SubSender does not exist'
RETURN ;
END
SELECT
#receiver = ID
FROM [dbo].[Party_Client]
WHERE
[Number] LIKE #receiver
IF(#receiverId IS NULL)
BEGIN
SET #ErrorMsg = 'Receiver does not exist'
RETURN;
END
SELECT
#subReceiverId = ID
FROM [dbo].[Party_Client]
WHERE
[Number] LIKE #subReceiver
AND ParentId = #receiverId
AND IsSubClient = 1
IF(#subReceiverId IS NULL)
BEGIN
SET #ErrorMsg = 'SubReceiver does not exist'
RETURN ;
END
SELECT #processId = ID FROM [dbo].[Party_Processes]
WHERE MsgTypeId = #msgTypeID
AND SenderId = #senderId
AND ReceiverId = #receiverId
END
And reading it with c# code:
using (SqlConnection connection = new SqlConnection(connectionString))
{
try
{
SqlCommand command = new SqlCommand("GetClients", connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("#sender", sender));
command.Parameters.Add(new SqlParameter("#subSender", subSender));
command.Parameters.Add(new SqlParameter("#receiver", receiver));
command.Parameters.Add(new SqlParameter("#subReceiver", subReceiver));
command.Parameters.Add(new SqlParameter("#msgTypeID", msgTypeID));
var errorMsgParam = command.Parameters.Add(new SqlParameter("#ErrorMsg", SqlDbType.NVarChar, -1));
errorMsgParam.Direction = ParameterDirection.Output;
var processIdParam = command.Parameters.Add(new SqlParameter("#processId", SqlDbType.Int, -1));
processIdParam.Direction = ParameterDirection.Output;
connection.Open();
command.ExecuteNonQuery();
var processIDResult = command.Parameters["#processId"].Value;
var errorMsgResult = command.Parameters["#ErrorMsg"].Value;
processID = (int)processIDResult;
errorMsg = errorMsgResult.ToString();
}
}
The thing is, I always get null as result. This is Helper class for xsl mapping in biztalk. All the input parameters are directly from the map. I want to check our database, if these clients exist and also, if process which using them exist.
thanks for your help :)
OK, i solved this. Problem was in 2 or 3 places. For first i had mistake in my SQL stored procedure which is not universal so i didnt post it here (it applies only to my project). The other mistake was in converting my output from stored procedure:
processID = command.Parameters["#processId"].Value as int?;
errorMsg = command.Parameters["#ErrorMsg"].Value == DBNull.Value ? string.Empty : command.Parameters["#ErrorMsg"].Value.ToString();
where processID is declared as "int?" and errorMsg is declared as "string".
Thanks for all the help.
I've tried everything to get this to work and I know I'm missing something very simple.
I have a method that calls a stored procedure to update a record in a table.
It just so happens that one of the parameters is nullable in the database and the program value for it comes in as an empty string ("") for the vehicleNo column in this particular kind of situation.
All the other records get updated except if an empty string comes in and I try and update the record with the stored procedure.
Can someone please point out what I need to add to make the stored procedure or code work correctly?
Below the code, I've tried executing the stored procedure with hard coded values, but neither updates with the ImageID.
Stored procedure
ALTER PROCEDURE [dbo].[SPR_UPDATE_IMAGEID]
#ticketNo int,
#vehicleNo varchar(6) = NULL,
#imageID varchar(20)
AS
BEGIN
IF ((#vehicleNo = '') OR (#vehicleNo IS NULL))
BEGIN
UPDATE dbo.HH_FuelTkt
SET Image_ID = #imageID
WHERE Ticket_No = #ticketNo
AND Vehicle_No = NULL
END
ELSE
BEGIN
UPDATE dbo.HH_FuelTkt
SET Image_ID = #imageID
WHERE Ticket_No = #ticketNo
AND Vehicle_No = #vehicleNo
END END
C# code:
public static bool UpdateData(int ticketNo, string vehicleNo, string imageID)
{
int retValue = 0;
try
{
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["HHInboundSqlConnection"].ToString()))
{
SqlCommand cmd = new SqlCommand("SPR_UPDATE_IMAGEID", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#ticketNo", ticketNo);
cmd.Parameters.AddWithValue("#vehicleNo", vehicleNo);
cmd.Parameters.AddWithValue("#imageID", imageID);
cmd.Connection.Open();
retValue = cmd.ExecuteNonQuery();
}
}
catch (Exception e)
{
throw e;
}
return (retValue > 0);
}
Manual stored procedure execution #1:
DECLARE #return_value int
EXEC #return_value = [dbo].[SPR_UPDATE_IMAGEID]
#ticketNo = 147058,
#vehicleNo = N'''''',
#imageID = N'39084'
SELECT 'Return Value' = #return_value
Manual stored procedure execution #2:
DECLARE #return_value int
EXEC #return_value = [dbo].[SPR_UPDATE_IMAGEID]
#ticketNo = 147058,
#vehicleNo = N'NULL',
#imageID = N'39084'
SELECT 'Return Value' = #return_value
IF ((#vehicleNo = '') OR (#vehicleNo IS NULL))
BEGIN
UPDATE dbo.HH_FuelTkt
SET Image_ID = #imageID
WHERE Ticket_No = #ticketNo
**AND Vehicle_No = NULL**
END
change the
AND Vehicle_No = NULL
to
AND Vehicle_No IS NULL
Normally on SQL check nullable value we use IS NULL instead of = NULL
I need to get resultSet and ReturnedValue from procedure.
My problem is that as i understand to get the returned value i need to execute the "ExecuteNonQuery()" and for the reader i need to execute "ExecuteReader()".
But this doesnt seems right that i call execute 2 times.
What is the currect way of doing so
using (OleDbConnection connection = new OleDbConnection(getConnetionString()))
{
using (OleDbCommand command = new OleDbCommand())
{
command.CommandText = "GamesApp.Images_Get";
command.Connection = connection;
command.CommandType = CommandType.StoredProcedure;
OleDbParameter retParameter = DBUtils.createReturnOleParam(OleDbType.Integer);
command.Parameters.Add(retParameter);
tmpParameter = DBUtils.createDBParam("#ImageID", OleDbType.Integer, ParameterDirection.Input, id);
command.Parameters.Add(tmpParameter);
command.Connection.Open();
command.ExecuteNonQuery();
int retValue = (int) retParameter.Value;
if (retValue == 0)
using (OleDbDataReader reader = command.ExecuteReader())
{
if (reader != null)
{
while (reader.Read())
{
Debug.WriteLine(reader.GetString(1));
}
reader.Close();
}
}
connection.Close();
}
}
GamesApp.Images_Get":
ALTER PROCEDURE [GamesApp].[Images_Get]
#ImageID SMALLINT
AS
BEGIN
SET NOCOUNT ON;
DECLARE #ErrorProc VARCHAR(500), #ErrorNumber INT, #ErrorSeverity INT, #ErrorState INT, #ErrorLine INT, #ErrorMessage VARCHAR(512)
DECLARE #ProcParams NVARCHAR(4000);
BEGIN TRY
--Check if #ImageID exists.if not error code is 1
IF NOT EXISTS (SELECT * FROM GamesApp.Images WHERE ImageID = #ImageID)
RETURN 1
SELECT ImageName, BG_Color, DisplayText, Text_Color, Text_Align, Text_Size
, ImageFormat, HtmlImageType, TheImage
FROM GamesApp.Images
WHERE ImageID = #ImageID;
RETURN 0;
END TRY
BEGIN CATCH
SELECT
#ErrorNumber = ERROR_NUMBER(),
#ErrorSeverity = ERROR_SEVERITY(),
#ErrorState = ERROR_STATE(),
#ErrorLine = ERROR_LINE(),
#ErrorMessage = ERROR_MESSAGE(),
#ErrorProc = 'GamesApp.Images_Get',
#ProcParams = '#ImageID' + #ImageID
EXEC dbo.Log_Exceptions_Insert #ErrorProc, #ProcParams, #ErrorLine, #ErrorNumber, #ErrorSeverity, #ErrorState, #ErrorMessage;
THROW;
END CATCH
END
I think there is no need to call ExecuteNonQuery()
As mentioned by #Damith you can use OleDbDataReader.HasRows
For verification you can look here and here