I am getting some unexpected error,
I have two two methods one is INSERTUPDATE & other is GETDATA
for INSERT UPDATE SP is -- >> spInsert_WorkEntry
for GETDATA SP is -- >> spGetWorkEntryData
for both the SP parameters are same as shown in the Image.
I am generating parameters dynamically. as shown in the CreateParams.
Creating parameter is same for both the methods for INSERTUPDATE & GETDATA.
Insert update method works fine & working as expected.
But when I tries to execute other method i.e. GETDATA it is giving me error that #OperatorName parameter is expected.
First parameter is #AutoID that parameter is not giving error.
I have checked all the possible scenarios that can be cauing issue but now get anything.
public int InsertOrUpdate(WorkEntry t, string callingPage, string operation)
{ // Start the Insert Update Method
IDbDataParameter[] param = null;
int returnValue = 0;
try
{
param = CreateParams(t, callingPage, operation);
param[0].Value = t.AutoID;
param[1].Value = t.OperatorName;
param[2].Value = t.Date;
param[3].Value = t.StartDate;
param[4].Value = t.EndDate;
SqlConnection sqlConnection = new SqlConnection(ConfigurationManager.AppSettings["ConnectionString"].ToString());
sqlConnection.Open();
SqlCommand command = sqlConnection.CreateCommand();
command.CommandType = System.Data.CommandType.StoredProcedure;
command.CommandText = "spInsert_WorkEntry";
command.Parameters.AddRange(param);
returnValue = command.ExecuteNonQuery();
sqlConnection.Close();
return returnValue;
}
catch (Exception ex)
{
return returnValue;
throw ex;
}
finally
{
param = null;
}
}// End the Insert Update Method
// Get-----------------------------------------------------------------------------------------
public DataSet Get(WorkEntry t, string callingPage, string operation)
{ // Start the Insert Update Method
IDbDataParameter[] param = null;
DataSet returnValue = new DataSet();
try
{
param = CreateParams(t, callingPage, operation);
param[0].Value = t.AutoID;
param[1].Value = t.OperatorName;
param[2].Value = t.Date;
param[3].Value = t.StartDate;
param[4].Value = t.EndDate;
SqlConnection sqlConnection = new SqlConnection(ConfigurationManager.AppSettings["ConnectionString"].ToString());
sqlConnection.Open();
SqlCommand command = sqlConnection.CreateCommand();
SqlDataAdapter da = new SqlDataAdapter(command);
command.CommandType = System.Data.CommandType.StoredProcedure;
command.CommandText = "spGetWorkEntryData";
command.Parameters.AddRange(param);
da.Fill(ds);
sqlConnection.Close();
return returnValue;
}
catch (Exception ex)
{
throw ex;
}
finally
{
param = null;
command.Parameters.Clear();
}
}// End the Insert Update Method
// Get End -----------------------------------------------------------------------------------------
public IDbDataParameter[] CreateParams(WorkEntry workEntry, string CallingPage, string Operation)
{
IDbDataParameter[] param = new IDbDataParameter[5];
param[0] = new SqlParameter();
param[0].DbType = DbType.Int32;
param[0].Size = 50;
param[0].ParameterName = "#AutoID";
param[0].Direction = ParameterDirection.Input;
param[1] = new SqlParameter();
param[1].DbType = DbType.String;
param[1].Size = 50;
param[1].ParameterName = "#OperatorName";
param[1].Direction = ParameterDirection.Input;
param[2] = new SqlParameter();
param[2].DbType = DbType.DateTime;
param[2].Size = 50;
param[2].ParameterName = "#Date";
param[2].Direction = ParameterDirection.Input;
param[3] = new SqlParameter();
param[3].DbType = DbType.DateTime;
param[3].Size = 50;
param[3].ParameterName = "#StartDate";
param[3].Direction = ParameterDirection.Input;
param[4] = new SqlParameter();
param[4].DbType = DbType.DateTime;
param[4].Size = 50;
param[4].ParameterName = "#EndDate";
param[4].Direction = ParameterDirection.Input;
return param;
}
Below is the image for SP
Try to move command.Parameters.AddRange(param); before SqlDataAdapter da = new SqlDataAdapter(command); statement
SqlConnection sqlConnection = new SqlConnection(ConfigurationManager.AppSettings["ConnectionString"].ToString());
sqlConnection.Open();
SqlCommand command = sqlConnection.CreateCommand();
command.Parameters.AddRange(param);
SqlDataAdapter da = new SqlDataAdapter(command);
command.CommandType = System.Data.CommandType.StoredProcedure;
command.CommandText = "spGetWorkEntryData";
da.Fill(ds);
Also for select statement if you are not using Where clause then maybe passing parameters is unnecessary.
Update: I tested it and its working fine on my example
some changes which I made into your Get Method
public DataSet Get(string callingPage, string operation)
{ // Start the Insert Update Method
// new instance of dataset and sqlcommand
DataSet ds = new DataSet();
SqlCommand command = new SqlCommand();
IDbDataParameter[] param = null;
DataSet returnValue = new DataSet();
try
{
param = CreateParams(callingPage, operation);
param[0].Value = 1;
param[1].Value = "";
param[2].Value = DateTime.Now;
param[3].Value = DateTime.Now;
param[4].Value = DateTime.Now;
// using connectin string property insted ConfigurationManager.AppSettings
SqlConnection sqlConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["Connection"].ConnectionString);
sqlConnection.Open();
command = sqlConnection.CreateCommand();
SqlDataAdapter da = new SqlDataAdapter(command);
command.CommandType = System.Data.CommandType.StoredProcedure;
command.CommandText = "spGetWorkEntryData";
command.Parameters.AddRange(param);
da.Fill(ds);
sqlConnection.Close();
return returnValue;
}
catch (Exception ex)
{
throw ex;
}
finally
{
param = null;
command.Parameters.Clear();
}
}// End
My Demo Stored procedure
Create proc [dbo].[spGetWorkEntryData]
#autoId int,
#operatorName varchar(100),
#date datetime,
#startDate datetime,
#enddate datetime
as
begin
select * from dbo.tblBinaryUsers
end
Result :
Remove all parameters from select query SP spGetWorkEntryData , it not need this ,
and your sp will be
create proc spGetWorkEntryData
as
begin
select operatorname, date, startdate ,enddate from workentry
end
Related
I am making a straightforward application using AngularJS and ASP.NET, which I am fairly new to. I created an SQL procedure but every time I have it executed, it throws the following error:
System.Data.SqlClient.SqlException: 'Procedure or function 'LoginProc'
expects parameter '#IsValid', which was not supplied.'
How do I resolve this exception? Here is the code for storing the procedure:
ALTER PROCEDURE LoginProc
#username VARCHAR(50),
#password VARCHAR(MAX),
#IsValid bit out
AS
BEGIN
SET #IsValid=(SELECT COUNT(username) from "User" WHERE username=N'#username' and password=N'#password')
END
And here is the code that attempts to execute the procedure:
public class db
{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings
["dbconnect"].ConnectionString);
public int userlogin(User user)
{
int res;
SqlCommand cmd = new SqlCommand("LoginProc", con);
cmd.CommandType = CommandType.StoredProcedure;
if (user.username != null && user.password != null) {
cmd.Parameters.AddWithValue("#username", user.username);
cmd.Parameters.AddWithValue("#password", user.password);
SqlParameter oblogin = new SqlParameter();
oblogin.ParameterName = "#IsVaild";
oblogin.Direction = ParameterDirection.Output;
oblogin.SqlDbType = SqlDbType.Bit;
cmd.Parameters.Add(oblogin);
con.Open();
cmd.ExecuteNonQuery();
res = Convert.ToInt32(oblogin.Value);
con.Close();
}
else
{
res = 0;
}
return res;
}
}
You have just mispelled #IsValid here:
oblogin.ParameterName = "#IsVaild";
public SqlDataReader GetDataReader(List<SqlParameter> parameterValues){
System.Data.SqlClient.SqlConnection cn = new System.Data.SqlClient.SqlConnection();
cn.ConnectionString = SQLConnectionObj.ConnectionString;
cn.Open();
System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand();
cmd.Parameters.AddRange(parameterValues.ToArray());
cmd.Connection = cn;
cmd.CommandText = SelectStatement;
cmd.CommandType = CommandType.Text;
return sReader = cmd.ExecuteReader();
}
When I try to add this for IN condition variable in select query,it fails.
Need to use this only for Fortify fix.Tried with dictionary Sql parameter.It works but increases the issue count up.
Please help me with this.And also if there is anything new which you want to add feel free to add those too.
But the following code works:-
public SqlDataReader GetDataReader(Dictionary<string, string> qParams)
{
SqlCommand SQLCommandObj = new SqlCommand(SelectStatement,
SQLConnectionObj);
string query=SelectStatement;
if (qParams.Count > 0)
{
foreach (string key in qParams.Keys)
{
string value = qParams[key];
SqlParameter par = new SqlParameter();
par.ParameterName = key;
par.Value = value;
SQLCommandObj.Parameters.Add(par);
}
}
foreach(SqlParameter par in SQLCommandObj.Parameters)
{
string key = par.ParameterName;
string value = par.Value as string;
query=query.Replace(key, value);
}
if (qParams.Count > 0)
{
SQLCommandObj.CommandText = "";
SQLCommandObj.CommandText = query;
}
SQLCommandObj.CommandTimeout = CustomCommandTimeout;
return SQLCommandObj.ExecuteReader(CommandBehavior.CloseConnection);
}
Where is the problem in my code?
I use a stored procedure and transaction.
For one parameter to be working properly, but when the number of parameters is more than one error occurs.
Where is my problem?
This is my code in C#
internal static bool ExecuteNonQueryTransaction(string CommandName, CommandType cmdType, SqlParameter[][] pars)
{
int result = 0;
SqlTransaction tr = null;
int h = pars.GetLength(0);
using (SqlConnection con = new SqlConnection(CONNECTION_STRING))
{
if (con.State != ConnectionState.Open)
{
con.Open();
}
try
{
tr = con.BeginTransaction();
using (SqlCommand cmd = con.CreateCommand())
{
cmd.CommandType = cmdType;
cmd.Transaction = tr;
cmd.CommandText = CommandName;
// cmd.Parameters.AddRange(pars);
for (int i = 0; i < pars.GetLength(0); i++)
{
cmd.Parameters.AddRange(pars[i]);
cmd.ExecuteNonQuery();
}
tr.Commit();
}
}
catch
{
if (tr != null)
{
tr.Rollback();
}
//return false;
}
}
return (result > 0);
}
and this my stored procedure
ALTER PROCEDURE dbo.AddNewUserTypePageAccess
(#id_user_type int,
#id_page_access int)
as
insert into user_type_page_access(id_user_type, id_page_access)
values(#id_user_type, #id_page_access)
return
Thank you for your help.....
You shouldn't call ExecuteNonQuery(); inside the loop that adds the parameters! Add all parameters, and then call ExecuteNonQuery(); once, with all the parameters in place.
Use this code:
using (SqlCommand cmd = con.CreateCommand())
{
cmd.CommandType = cmdType;
cmd.Transaction = tr;
cmd.CommandText = CommandName;
// cmd.Parameters.AddRange(pars);
for (int i = 0; i < pars.GetLength(0); i++)
{
cmd.Parameters.AddRange(pars[i]);
}
// call ExecuteNonQuery only AFTER you've added all the parameters!
cmd.ExecuteNonQuery();
tr.Commit();
}
This is my stored procedure:
ALTER PROCEDURE [dbo].[NextPrevPost]
#PostQueryString NVARCHAR(100),
#NextID INT OUTPUT,
#NextTitle NVARCHAR(500) OUTPUT,
#NextPostDate DATETIME OUTPUT,
#NextQueryString NVARCHAR(100) OUTPUT,
#PrevID INT OUTPUT,
#PrevTitle NVARCHAR(500) OUTPUT,
#PrevPostDate DATETIME OUTPUT,
#PrevQueryString NVARCHAR(100) OUTPUT
AS
BEGIN
DECLARE #ID INT;
SELECT #ID=PostID FROM Post WHERE PostQueryString=#PostQueryString;
SELECT TOP 1
#NextID = COALESCE(P.PostID,0),
#NextTitle = P.PostTitle,
#NextPostDate = COALESCE(P.PostDate, getdate()),
#NextQueryString = P.PostQueryString
FROM
Post P
WHERE
P.PostDate >= (SELECT PostDate FROM Post WHERE PostID = #ID)
AND P.PostID != #ID
ORDER BY
PostDate ASC
SELECT TOP 1
#PrevID = COALESCE(P.PostID, 0),
#PrevTitle = P.PostTitle,
#PrevPostDate = COALESCE(P.PostDate, GETDATE()),
#PrevQueryString = P.PostQueryString
FROM
Post P
WHERE
P.PostDate <= (SELECT PostDate FROM Post WHERE PostID = #ID)
AND P.PostID != #ID
ORDER BY
PostDate DESC
IF(#PrevPostDate IS NULL)
BEGIN
SET #PrevPostDate = GETDATE();
END
IF(#NextPostDate IS NULL)
BEGIN
SET #NextPostDate = GETDATE();
END
SET #PrevPostDate=GETDATE();
SET #NextPostDate=GETDATE();
And this is my c# function that call the previous stored procedure:
private void SetNextPrev(string s)
{
SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["BlogConnectionString"].ConnectionString);
SqlCommand command = new SqlCommand("NextPrevPost",connection);
connection.Open();
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("PostQueryString", DbType.String)).Value = s;
SqlParameter nextid = new SqlParameter("NextID", DbType.Int32);
nextid.Direction = ParameterDirection.Output;
command.Parameters.Add(nextid);
SqlParameter nexttitle = new SqlParameter("NextTitle", DbType.String);
nexttitle.Direction = ParameterDirection.Output;
command.Parameters.Add(nexttitle);
SqlParameter NextPostDate = new SqlParameter("NextPostDate", DbType.DateTime);
NextPostDate.Direction = ParameterDirection.Output;
command.Parameters.Add(NextPostDate);
SqlParameter NextQueryString = new SqlParameter("NextQueryString", DbType.String);
NextQueryString.Direction = ParameterDirection.Output;
command.Parameters.Add(NextQueryString);
SqlParameter prevtid = new SqlParameter("PrevID", DbType.Int32);
prevtid.Direction = ParameterDirection.Output;
command.Parameters.Add(prevtid);
SqlParameter prevtitle = new SqlParameter("PrevTitle", DbType.String);
prevtitle.Direction = ParameterDirection.Output;
command.Parameters.Add(prevtitle);
SqlParameter PrevPostDate = new SqlParameter("PrevPostDate", DbType.DateTime);
PrevPostDate.Direction = ParameterDirection.Output;
command.Parameters.Add(PrevPostDate);
SqlParameter PrevQueryString = new SqlParameter("PrevQueryString", DbType.String);
PrevQueryString.Direction = ParameterDirection.Output;
command.Parameters.Add(PrevQueryString);
try
{
command.ExecuteNonQuery();
if (prevtid.Value.ToString()!=string.Empty)
{
}
if (nextid.Value.ToString()!=string.Empty)
{
}
}
catch { }
finally { command.Dispose(); connection.Close(); }
}
I got the error:
Implicit conversion from data type datetime to int is not allowed. Use the CONVERT function to run this query.
Why?
Thanks!
UPDATE!
#BoStigChristensen
I changed from DbType into SqlDbType type. So my c# function looks like that:
private void SetNextPrev(string s)
{
SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["BlogConnectionString"].ConnectionString);
SqlCommand command = new SqlCommand("NextPrevPost",connection);
connection.Open();
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("PostQueryString", SqlDbType.NVarChar)).Value = s;
SqlParameter nextid = new SqlParameter("NextID", SqlDbType.Int);
nextid.Direction = ParameterDirection.Output;
command.Parameters.Add(nextid);
SqlParameter nexttitle = new SqlParameter("NextTitle", SqlDbType.NVarChar);
nexttitle.Direction = ParameterDirection.Output;
command.Parameters.Add(nexttitle);
SqlParameter NextPostDate = new SqlParameter("NextPostDate", SqlDbType.DateTime);
NextPostDate.Direction = ParameterDirection.Output;
command.Parameters.Add(NextPostDate);
SqlParameter NextQueryString = new SqlParameter("NextQueryString", SqlDbType.NVarChar);
NextQueryString.Direction = ParameterDirection.Output;
command.Parameters.Add(NextQueryString);
SqlParameter prevtid = new SqlParameter("PrevID", SqlDbType.Int);
prevtid.Direction = ParameterDirection.Output;
command.Parameters.Add(prevtid);
SqlParameter prevtitle = new SqlParameter("PrevTitle", SqlDbType.NVarChar);
prevtitle.Direction = ParameterDirection.Output;
command.Parameters.Add(prevtitle);
SqlParameter PrevPostDate = new SqlParameter("PrevPostDate", SqlDbType.DateTime);
PrevPostDate.Direction = ParameterDirection.Output;
command.Parameters.Add(PrevPostDate);
SqlParameter PrevQueryString = new SqlParameter("PrevQueryString", SqlDbType.NVarChar);
PrevQueryString.Direction = ParameterDirection.Output;
command.Parameters.Add(PrevQueryString);
try
{
command.ExecuteNonQuery();
if (prevtid.Value.ToString()!=string.Empty)
{
}
if (nextid.Value.ToString()!=string.Empty)
{
}
}
catch { }
finally { command.Dispose(); connection.Close(); }
}
But unfortunately it throw the error:
String[2]: the Size property has an invalid size of 0.
SqlParameter constructor takes a SqlDbType and not DbType:
SqlParameter(String, SqlDbType)
Pass the correct type SqlDbType :-)
By passing DbType.DateTime into a SqlDbType parameter, you are basically passing a potentially wrong mapping, leading to unpredictable results.
An example of this:
using System;
using System.Data;
using System.Data.SqlClient;
namespace ConsoleApplication1 {
class Program {
static void Main(string[] args) {
const SqlDbType MY_SQL_ENUM = new SqlDbType();
const DbType MY_DB_ENUM = new DbType();
var wrongParam = new SqlParameter("WrongTest", DbType.DateTime);
Console.WriteLine(Enum.GetName(MY_DB_ENUM.GetType(), wrongParam.DbType));
Console.WriteLine(Enum.GetName(MY_SQL_ENUM.GetType(), wrongParam.SqlDbType));
var rightParam = new SqlParameter("RightTest", SqlDbType.DateTime);
Console.WriteLine(Enum.GetName(MY_DB_ENUM.GetType(), rightParam.DbType));
Console.WriteLine(Enum.GetName(MY_SQL_ENUM.GetType(), rightParam.SqlDbType));
Console.ReadKey();
}
}
}
I am passing string _nameProcessed from the UI to my DAL and updating my table. Now when I am doing the foreach look I could not figure if out how to Update my column ShipmentProcessedBy to _nameProcessed.
Any help guys???
public void SaveNameProcessed(DataTable updatedTable, string _nameProcessed)
{
foreach (DataRow row in updatedTable.Rows)
{
SqlCommand cmd2 = new SqlCommand(
#"update dbo.JobStatus
SET ShipmentProcessedBy = ????,
WHERE JobTableId = #JobID ", _mySqlConnec);
//Updated the parameters to the SQL Query!
cmd2.Parameters.Add(new SqlParameter("#ProcessedBy", row["ProcessedBy"].ToString()));
cmd2.Parameters.Add(new SqlParameter("#JobID", row["JobID"].ToString()));
cmd2.Connection = _mySqlConnec;
_mySqlConnec.Open();
cmd2.ExecuteNonQuery();
_mySqlConnec.Close();
}
}
Here is the rectified code:
public void SaveNameProcessed(DataTable updatedTable, string _nameProcessed)
{
foreach (DataRow row in updatedTable.Rows)
{
SqlCommand cmd2 = new SqlCommand(
#"update dbo.JobStatus
SET ShipmentProcessedBy = ????,
WHERE JobTableId = #JobID ", _mySqlConnec);
//Updated the parameters to the SQL Query!
cmd2.Parameters.Add(new SqlParameter("#ProcessedBy", _nameProcessed));
cmd2.Parameters.Add(new SqlParameter("#JobID", row["JobID"].ToString()));
cmd2.Connection = _mySqlConnec;
_mySqlConnec.Open();
cmd2.ExecuteNonQuery();
_mySqlConnec.Close();
}
}
You have declared and added a parameter called #ProcessedBy so just set it to that in your SQL.
SET ShipmentProcessedBy = #ProcessedBy,
Exactly the same as you have done with #JobId
You also need to change this line:
cmd2.Parameters.Add(new SqlParameter("#ProcessedBy", row["ProcessedBy"].ToString()));
to
cmd2.Parameters.Add(new SqlParameter("#ProcessedBy", _nameProcessed));