In T-SQL I have an exec like this:
EXEC [dbo].[usp_TaskStatus_Time_Calculation_Final]
#EmployeeGuidIdTableType = #EmployeeGuidIdTableType,
#StartingDate = '2018-08-02 00:00:00.000',
#EndingDate = '2018-08-08 00:00:00.000'
It works correctly, parameters do their job correctly, so I want to reproduce this in C# and I do:
public DataTable ExeSQLParamAndType(string SprocName, DataTable paramArray, string tableTypeName, string parameters = null)
{
SqlCommand cmd = new SqlCommand(SprocName, this.dbconn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter(tableTypeName, SqlDbType.Structured));
cmd.Parameters[tableTypeName].Value = paramArray;
cmd.Parameters.Add(new SqlParameter(parameters, SqlDbType.NVarChar));
DataTable tbl = new DataTable("Table1")
{
Locale = System.Globalization.CultureInfo.InvariantCulture
};
SqlDataAdapter da = new SqlDataAdapter(cmd);
try
{
da.Fill(tbl);
}
catch (SqlException e)
{
this.HandleSQLError(e, "GetTableBySQL", SprocName);
}
finally
{
cmd.Dispose();
}
return tbl;
}
Execute method:
db.ExeSQLParamAndType("StoredProcedureCalc", parameters,
"#EmployeeGuidIdTableType",
$"#StartingDate = '{startDate}', #EndingDate = '{endDate}'");
I get an exception when trying to pass StaringDate and EndingDate parameter in line this.HandleSQLError(e, "GetTableBySQL", SprocName);
#StartingDate = ''2018-08-02 00:00:00.000'', #EndingDate = ''2018-08-08 00:00:00.000'' is not a parameter for procedure StoredProcedureCalc
Someone see something wrong there? Regards
Note: If I execute it from c# without this two parameters (just with table type) it works
Update
I change my code as comments below to:
var startDate = $"'{startingDate.Value.ToString("yyyy-MM-dd 00:00:00.000")}'";
var endDate = $"'{endingDate.Value.ToString("yyyy-MM-dd 00:00:00.000")}'";
db.ExeSQLParamAndType("usp_TaskStatus_Time_Calculation_Final", parameters, "#EmployeeGuidIdTableType", startDate, endDate);
and method like:
public DataTable ExeSQLParamAndType(string sprocName, DataTable paramArray, string tableTypeName, string startingDate, string endingDate)
{
SqlCommand cmd = new SqlCommand(sprocName, this.dbconn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter(tableTypeName, SqlDbType.Structured));
cmd.Parameters[tableTypeName].Value = paramArray;
DateTime.TryParse(startingDate, out var startDate);
cmd.Parameters.Add(new SqlParameter("#StartingDate", SqlDbType.DateTime));
cmd.Parameters["#StartingDate"].Value = startDate;
DateTime.TryParse(startingDate, out var endDate);
cmd.Parameters.Add(new SqlParameter("#EndingDate", SqlDbType.DateTime));
cmd.Parameters["#EndingDate"].Value = endDate;
DataTable tbl = new DataTable("Table1")
{
Locale = System.Globalization.CultureInfo.InvariantCulture
};
SqlDataAdapter da = new SqlDataAdapter(cmd);
try
{
da.Fill(tbl);
}
catch (SqlException e)
{
this.HandleSQLError(e, "GetTableBySQL", sprocName);
}
finally
{
cmd.Dispose();
}
return tbl;
}
But I have troubles with DateTime, how can I parse as desire output format: 2018-08-02 00:00:00.000 ?
The problems is caused because
cmd.Parameters.Add(new SqlParameter(parameters, SqlDbType.NVarChar));
is creating a parameter with the name of whatever value is held in the variable parameters which is the string value "#StartingDate = '{startDate}', #EndingDate = '{endDate}'" because that is what you passed into ExeSQLParamAndType with this code:
db.ExeSQLParamAndType("StoredProcedureCalc"
, parameters
, "#EmployeeGuidIdTableType"
,$"#StartingDate = '{startDate}', #EndingDate = '{endDate}'");
you need to create two parameters, one called startDate and one called EndDate
cmd.Parameters.Add(new SqlParameter(startingDate, SqlDbType.NVarChar));
cmd.Parameters.Add(new SqlParameter(EndingDate , SqlDbType.NVarChar));
C# DateTime and SQL Server DateTime are incompatible. You must change the setting in your SQL tables to use Datetime2 not DateTime. You can do this by directly issuing an ALTER statement to every table with a Datetime field in your Database or adding a one line command in your DbContext class telling Entity Framework to specifically use "datetime2" for all classes that use DateTime.
Related
This code keeps bringing up a:
Failed to convert parameter value from a String to a Boolean.
public void BindToData()
{
try
{
DataSet ds = new DataSet();
string connString = #"Data Source=(LocalDb)\MSSQLLocalDB;Initial Catalog=DesignSaoOsig1;Integrated Security=True";
string strproc = "TestReport";
using (SqlDataAdapter sda = new SqlDataAdapter(strproc, connString))
{
SqlCommand cmd = new SqlCommand();
sda.SelectCommand.CommandType = CommandType.StoredProcedure;
sda.SelectCommand.Parameters.Add("#Status", SqlDbType.Bit).Value = StatusId.SelectedValue;
sda.SelectCommand.Parameters.Add("#OrgJed", SqlDbType.Int).Value = orgUnitId.SelectedValue;
sda.Fill(ds);
XtraReport report = new XtraReport();
report.DataSource = ds;
}
}
catch (Exception)
{
throw;
}
}
Stored Procedure
ALTER PROCEDURE [dbo].[TestReport]
(
#Status bit,
#OrgJed int
)
AS
BEGIN
SELECT TOP 1 OrgUnitID
FROM tblZaposleni_AD
WHERE Status = #Status AND
OrgUnitID = #OrgJed
END
I have looked everywhere and there have been suggestions to do converts, but I simply can't find what exactly I should have to convert in this code.
The problem is here, and I try everything but doesn't work.
sda.SelectCommand.Parameters.Add("#Status", SqlDbType.Bit).Value = StatusId.SelectedValue;
sda.SelectCommand.Parameters.Add("#OrgJed", SqlDbType.Int).Value = orgUnitId.SelectedValue;
Note: StatusId is DropDownMenu which has 2 options, "0" or "1". OrgJed is DropDownMenu which has values from "1" to "10"
You need to convert the strings in your DropDownLists to a bool and an int respectively for use in your parameters e.g.
sda.SelectCommand.Parameters.Add("#Status", SqlDbType.Bit).Value = StatusId.SelectedValue == "1" ? true : false;
sda.SelectCommand.Parameters.Add("#OrgJed", SqlDbType.Int).Value = Int32.Parse(orgUnitId.SelectedValue);
Note: For robust code you should really use Int32.TryParse() but I will leave that as an exercise for you.
I am generating a report through sending some parameter from C# code to a SQL Server stored procedure. I am sending a string value and two date values as a SQL Server procedure parameters, but I having some problems with the date parameter. I have checked my SQL Server stored procedure; when manually passing a value, it is returning the correct results, but when I am passing the parameter value from my code, it is showing nothing in report.
SQL Server stored procedure:
[GetLedger]
(#optb VARCHAR(50),
#startsession DATE,
#endsession DATE)
AS
DECLARE #openingtable
DECLARE #strtdt DATE
DECLARE #enddate DATE
DECLARE #query NVARCHAR(MAX)
BEGIN
SET #openingtable = #optb
SET #strtdt = #startsession
SET #enddate = #endsession
SET #query = N'SELECT l.trandate,l.voucherno,l.itemno,l.itemname,o.opening + COALESCE(SUM(l.recieve - l.returnback - l.issue) OVER (PARTITION BY l.itemno ORDER BY l.trandate,seq ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING),0) AS opening,l.recieve,l.returnback,l.issue,o.opening + SUM(l.recieve - l.returnback - l.issue) OVER (PARTITION BY l.itemno ORDER BY l.trandate,seq) AS balance,l.to_dept,l.remarks
FROM #openingstock o
INNER JOIN
(
SELECT trandate,voucherno,itemno,itemname,to_dept,remarks,isnull(recieve,0) AS recieve,isnull(issue,0) AS issue,isnull(returnback,0) AS returnback,
row_number() over (partition by itemno,trandate order by itemno) as seq
FROM #ledgertable
) l
ON l.itemno = o.itemno
where l.trandate between CONVERT(Date,''' + CONVERT(VARCHAR(10),#strtdt, 101)+''', 101) and CONVERT(DATE,'''+ CONVERT(VARCHAR(10),DATEADD(DD,1,#enddate),101) + ''', 101)
ORDER BY l.itemno,trandate'
EXECUTE(#query)
END
C# code is:
private ledgerdt GetData(string p1,string p2,string p3)
{
string DateString = p2;
IFormatProvider culture = new CultureInfo("en-US", true);
DateTime pp2 = DateTime.ParseExact(DateString, "yyyy-MM-dd", culture);
string DateString2 = p2;
IFormatProvider culture2 = new CultureInfo("en-US", true);
DateTime pp3 = DateTime.ParseExact(DateString, "yyyy-MM-dd", culture2);
using (SqlConnection con = new SqlConnection(conString))
{
SqlCommand cmd = new SqlCommand("GetLedger", con);
using (SqlDataAdapter sda = new SqlDataAdapter())
{
cmd.Connection = con;
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#optb", p1);
cmd.Parameters.AddWithValue("#startsession", pp2.ToString("yyyy-MM-dd"));
cmd.Parameters.AddWithValue("#endsession", pp3.ToString("yyyy-MM-dd"));
sda.SelectCommand = cmd;
using (ledgerdt ds = new ledgerdt())
{
sda.Fill(ds, "ledgerdt");
return ds;
}
}
}
Please tell the solution..... I know that I am doing something wrong in data type.
Added the code using Add instead of AddWithValue:
using (SqlConnection con = new SqlConnection(conString))
using (SqlCommand cmd = new SqlCommand("GetLedger", con))
using (SqlDataAdapter sda = new SqlDataAdapter())
{
cmd.Connection = con;
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SQLParameter("#optb", Data.SqlDbType.VarChar);
cmd.Parameters.Add(new SQLParameter("#startsession", Data.SqlDbType.DateTime));
cmd.Parameters.Add(new SQLParameter("#endsession", Data.SqlDbType.DateTime));
command.Parameters("#optb").Value = p1;
command.Parameters("#startsession").Value = pp2;
command.Parameters("#startsession").Value = pp3;
sda.SelectCommand = cmd;
using (ledgerdt ds = new ledgerdt())
{
sda.Fill(ds, "ledgerdt");
return ds;
}
}
I have a custom SQL exec to execute stored procedure and send DataTable and execute TableType in sql like:
//Execute
db.ExeSQLParam("usp_TaskStatus_Time_Calculation_Final", parameters, "#GuidIdTableType");
ExeSQLParam method:
public bool ExeSQLParam(string SprocName, DataTable paramArray, string tableTypeName)
{
var testc = new SqlParameter();
bool bFlag = false;
SqlCommand cmd = new SqlCommand(SprocName, this.dbconn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter(tableTypeName, SqlDbType.Structured));
cmd.Parameters[tableTypeName].Value = paramArray;
try
{
cmd.ExecuteNonQuery();
bFlag = true;
}
catch (SqlException e)
{
this.HandleSQLError(e, SprocName, paramArray.ToString());
}
finally
{
cmd.Dispose();
}
return bFlag;
}
My question is how can I add to this method another normal parameters , so I can execute as:
db.ExeSQLParam("usp_TaskStatus_Time_Calculation_Final", parameters, "#GuidIdTableType",
#anoteherParameter = 'valueanotherparameter', #other = 'valueoter');
How can I achieve that?
I try to change it to received output data as DataTable like:
public DataTable ExeSQLParamAndType(string SprocName, DataTable paramArray, string tableTypeName)
{
SqlCommand cmd = new SqlCommand(SprocName, this.dbconn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter(tableTypeName, SqlDbType.Structured));
cmd.Parameters[tableTypeName].Value = paramArray;
DataTable tbl = new DataTable("Table1")
{
Locale = System.Globalization.CultureInfo.InvariantCulture
};
SqlDataAdapter da = new SqlDataAdapter(cmd);
try
{
da.Fill(tbl);
}
catch (SqlException e)
{
this.HandleSQLError(e, "GetTableBySQL", SprocName);
}
finally
{
cmd.Dispose();
}
return tbl;
}
but where I can add new parameters? with another parameters.Add? I'm a litte confused there
In C# you can provide optional parameters using the 'params' keyword, so you simply rewrite your method and supply the params parametres.
In the ShippedContainerSettlement program I am trying to add parameters to a SQL statement on a stored procedure that I created on the remote server (plex).
public void checkGradedSerials()
{
localTable = "Graded_Serials";
List<string> gradedHides = new List<string>();
string queryString = "call sproc164407_2053096_650214('#startDate', '" + endDate + "');";
OdbcDataAdapter adapter = new OdbcDataAdapter();
OdbcCommand command = new OdbcCommand(queryString, connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("#startDate", startDate);
adapter.SelectCommand = command;
connection.Open();
while (rowsCollected == false)
{
if (retries <= 5)
{
try
{
DataTable table = new DataTable();
adapter.Fill(table);
An error is thrown when I use the parameter #startDate and give it a value. However, when I run the program, and add the parameters how I have done for endDate, it runs fine?
The error I get back is:
Any ideas what I am doing wrong.
EDIT:
I have incorporated some of the changes mentioned below. Here is the code I used.
public void checkGradedSerials()
{
localTable = "Graded_Serials";
List<string> gradedHides = new List<string>();
OdbcCommand command = new OdbcCommand("sproc164407_2053096_650214", odbcConnection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("#startDate", startDate);
command.Parameters.AddWithValue("#endDate", endDate);
OdbcDataAdapter adapter = new OdbcDataAdapter();
adapter.SelectCommand = command;
odbcConnection.Open();
while (rowsCollected == false)
{
if (retries <= 5)
{
try
{
DataTable table = new DataTable();
adapter.Fill(table);
But it doesn't seem to be receiving the parameters i am sending through as I am getting this error.
Here is the stored procedure I am using. This might look odd but remember this is working when I simply pass a string into a select command (see endDate in first code example above).
SELECT DISTINCT(Serial_No)
FROM Part_v_Container_Change2 AS CC
WHERE CC.Change_Date > #Change_Start_Date AND
CC.Change_Date <= #Change_End_Date AND
CC.Location = 'H Grading';
and the parameters are added here:
You should use the System.Data.SqlClient. You can explicitly declare the datatypes of paramaters you are sending... like this:
SqlConnection cn;
cn = new SqlConnection(ConnectionString);
SqlCommand cmd;
cmd = new SqlCommand("sproc164407_2053096_650214", cn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#startDate", SqlDbType.DateTime);
cmd.Parameters["#startDate"].Value = startDate;
cmd.Parameters.Add("#enddate", SqlDbType.VarChar);
cmd.Parameters["#enddate"].Value = enddate;
If you must use the ODBC, then you do have to use the ODBC CALL syntax, which does not support named parameters. So change your queryString line to:
string queryString = "{call sproc164407_2053096_650214 (?, ?)}";
Then you can add your parameters:
command.Parameters.Add("#startDate", OdbcType.DateTime).Value=startDate;
command.Parameters.Add("#endDate", OdbcType.DateTime).Value=endDate;
Use SqlCommand instead of odbc.
Just put the stored proc name in the CommandText, not a SQL statement to execute it. Adding the param values means the adapter will pass in the params in the right format. You don't need to do the string manipulation in CommandText.
If you need to use OdbcCommand then see this answer showing you need to use ? syntax for the parameters, so maybe change your CommandText back to including the 'call' or 'exec' command and parameter placeholders, then make sure you AddWithValue the params in the right order
I'm trying to insert date time picker value into a DATETIME column in my database.
Here's my code..
myconstr = "Data Source=wind;Initial Catalog=TestDB;Integrated Security=True;Connect Timeout=15;Encrypt=False;TrustServerCertificate=False";
myquery = "INSERT INTO DateTimeTB(MyDate) VALUES (#mydate)";
using (SqlConnection connection = new SqlConnection(myconstr))
{
SqlCommand cmd = new SqlCommand(myquery);
cmd.CommandType = CommandType.Text;
cmd.Connection = connection;
cmd.Parameters.Add(new SqlParameter("#mydate", SqlDbType.DateTime).Value = MyDTP01.Value);
connection.Open();
cmd.ExecuteNonQuery();
connection.Close();
}
It gives me the following error..
The SQL parameter collection only accepts non-null SqlParameter type objects, not date time objects.
How can I fix this..?
Your code is equivalent to:
var parameter = new SqlParameter("#mydate", SqlDbType.DateTime);
var value = MyDTP01.Value;
parameter.Value = value;
cmd.Parameters.Add(value);
You want to add the parameter, not the value. So:
cmd.Parameters.Add(new SqlParameter("#mydate", SqlDbType.DateTime)).Value = MyDTP01.Value;
Note the location of the brackets.
This can be simplified, however - you don't need to call the SqlParameter constructor yourself - you can just pass the name and the type to Add:
cmd.Parameters.Add("#mydate", SqlDbType.DateTime).Value = MyDTP01.Value;
Using Enterprise Library, This is how I do it
var db = EnterpriseLibraryContainer.Current.GetInstance<Database>();
using( DbCommand command = db.GetStoredProcCommand("Your Stored proc name"))
{
db.AddInParameter(command, "#mydate", DbType.DateTime, DateTime.Now.Date); // Replace with MyDTP01.Value
db.ExecuteNonQuery(command);
}