SQL Server DataAdapter is not filling datatable - sql

I am running code to fill a dataset from a SQL Server table, but for some reason it is not filling the datatable. I have run the stored procedure with the values when stepping through the code and it returns rows. I have checked via SQL Server Profiler what command runs and then executed the same command through SQL Server Management Studio and it returns rows, but for some reason in Visual Studio it returns no rows, yet it is not returning any exception.
The code is :
try
{
using (SqlConnection cnn = new SqlConnection(ConfigurationManager.ConnectionStrings["Intranet"].ConnectionString))
{
switch (command)
{
case "radiobutton":
string school = ParameterString[0];
using (SqlDataAdapter da = new SqlDataAdapter(GET_TEMPLATE_NAMES, cnn))
{
DataTable dt = new DataTable();
da.SelectCommand.CommandType = CommandType.StoredProcedure;
da.SelectCommand.Parameters.AddWithValue("#TemplateforSchool", school);
cnn.Open();
da.Fill(dt);
lstTemplates.DataSource = dt;
lstTemplates.DataBind();
}
break;
case "listbox": // If the listbox triggers the callback then update the grid
switch (radSchools.SelectedItem.Text)
{
case "Junior School":
StartYear = 1;
EndYear = 5;
break;
case "Middle School":
StartYear = 6;
EndYear = 8;
break;
case "Senior School":
StartYear = 9;
EndYear = 12;
break;
}
string TemplateName = ParameterString[0];
int DetentionCount = Convert.ToInt16(ParameterString[1]);
string DetentionType = ParameterString[2];
using (SqlDataAdapter da = new SqlDataAdapter(GET_CAREGIVER_EMAIL_LIST, cnn))
{
DataTable dt = new DataTable();
da.SelectCommand.CommandType = CommandType.StoredProcedure;
da.SelectCommand.Parameters.Add(new SqlParameter
{
ParameterName = "#DetentionType",
SqlDbType = SqlDbType.VarChar,
Value= DetentionType
});
da.SelectCommand.Parameters.Add(new SqlParameter
{
ParameterName="#DetentionCounter",
SqlDbType=SqlDbType.Int,
Value=DetentionCount
});
da.SelectCommand.Parameters.Add(new SqlParameter
{
ParameterName = "#StartYear",
SqlDbType = SqlDbType.Int,
Value = StartYear
});
da.SelectCommand.Parameters.Add(new SqlParameter
{
ParameterName = "#EndYear",
SqlDbType = SqlDbType.Int,
Value = EndYear
});
cnn.Open();
da.Fill(dt);
gdvCaregiverEmailList.DataSource = dt;
gdvCaregiverEmailList.DataBind();
}
break;
}
}
}
catch(Exception ex)
{
}
The problem is in the listbox: section of the switch statement. The SqlDataAdapter works fine in the radio button section of the switch.
I am not sure what I am missing so any help would be much appreciated.
I have checked SqlDataAdapter does not fill DataSet and also SqlDataAdapter not filling DataTable but the first was not relevant to my situation and the second had no accepted answer that I could find.
The SQL Server stored procedure that I am calling is
ALTER PROCEDURE [dbo].[GetCaregiverEmailList]
#DetentionType CHAR(2),
#DetentionCounter INT,
#StartYear INT,
#EndYear INT
AS
BEGIN
SELECT DISTINCT
sdc.StudentCode, s.Student#, s.GIVEN_NAME, s.SURNAME,
sdc.DetentionCount, sdc.DetentionType,
s.GIVEN_NAME + ' ' + s.SURNAME AS FullName,
LTRIM(s.CURRENT_YEAR) AS CurrentYear,
i.EMAIL_HOME, RTRIM(i.SALUTATION) AS EmailTitle,
ax.CORR_PREFERENCE, ar.CAREGIVER_NO
FROM
StudentDetentionCounter sdc
LEFT JOIN
[PCSchool].[dbo].[Student] s ON sdc.StudentCode = s.STUDENT#
INNER JOIN
[PCSchool].[dbo].[ALUMREL] ar ON sdc.StudentCode = ar.CHILD#
LEFT JOIN
[PCSchool].[dbo].[IDENTITY] i ON ar.PARENT# = i.[MEMBER#]
LEFT JOIN
[PCSchool].[dbo].[ALUMREL_EX] ax ON ar.parent# = ax.PARENT#
WHERE
(ar.PARENT# <> ar.FAMILY_HASH)
AND ar.EN_EMAIL IN ('I','A')
AND (ax.CORR_PREFERENCE = 1)
AND (sdc.DetentionCount = #DetentionCounter
AND sdc.DetentionType = #DetentionType)
AND (CONVERT(INT, (LTRIM(s.CURRENT_YEAR))) BETWEEN #StartYear AND #EndYear)
ORDER BY
s.SURNAME
END
The command that is executed when I look at SQL Server Profiler is
exec GetCaregiverEmailList #DetentionType='LT',#DetentionCounter=3,#StartYear=9,#EndYear=12
And the following are the rows that are returned if I execute the stored procedure manually or running the above exec command.
Any suggestions or help would be much appreciated.
Regards,
Darren

Related

.NET Query with list as sql parameter

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);
}

Update SQL table very slow

I have problem when I try to update SQL table with
I have datagridview and I need to update SQL table and take the value form my datagridview . my datagridview have more than 10000 rows
I take time more than 1:30 hour very slow
datagridview name "dgv_balance"
Here is the code:
using (SqlConnection cn = new SqlConnection())
{
cn.ConnectionString = "My Connection"
cn.Open();
using (SqlCommand cmd_select = new SqlCommand())
{
for (int i = 0; i < dgv_balance.RowCount; i++)
{
cmd_select.Connection = cn;
cmd_select.CommandType = CommandType.StoredProcedure;
cmd_select.CommandText = "clients_balances_select_glid_date";
cmd_select.Parameters.AddWithValue("#glid", Convert.ToString(dgv_balance.Rows[i].Cells[0].Value));
cmd_select.Parameters.AddWithValue("#date", Convert.ToDateTime(dgv_balance.Rows[i].Cells[2].Value));
if (cmd_select.ExecuteScalar().ToString()=="")
{
using (SqlCommand cmd_insert = new SqlCommand())
{
cmd_insert.Connection = cn;
cmd_insert.CommandType = CommandType.StoredProcedure;
cmd_insert.CommandText = "clients_balances_insert_data";
cmd_insert.Parameters.AddWithValue("#glid", Convert.ToString(dgv_balance.Rows[i].Cells[0].Value));
cmd_insert.Parameters.AddWithValue("#name", Convert.ToString(dgv_balance.Rows[i].Cells[1].Value));
cmd_insert.Parameters.AddWithValue("#date", Convert.ToString(dgv_balance.Rows[i].Cells[2].Value));
cmd_insert.Parameters.AddWithValue("#balance", Convert.ToString(dgv_balance.Rows[i].Cells[3].Value));
cmd_insert.ExecuteNonQuery();
cmd_insert.Parameters.Clear();
}
}
else
{
using (SqlCommand cmd_update= new SqlCommand())
{
cmd_update.Connection = cn;
cmd_update.CommandType = CommandType.StoredProcedure;
cmd_update.CommandText = "clients_balances_update_balance";
cmd_update.Parameters.AddWithValue("#glid", Convert.ToString(dgv_balance.Rows[i].Cells[0].Value));
cmd_update.Parameters.AddWithValue("#date", Convert.ToString(dgv_balance.Rows[i].Cells[2].Value));
cmd_update.Parameters.AddWithValue("#balance", Convert.ToString(dgv_balance.Rows[i].Cells[3].Value));
cmd_update.ExecuteNonQuery();
cmd_update.Parameters.Clear();
}
}
cmd_select.Parameters.Clear();
}
}
}
You may have to call SELECT command for one time only before you loop through your datagridview rows and cache the result data and check on the result while iterating your datagridview instead of calling it on each row. This way you will reduce your commands by 10000.
It also better if you could show us your procedures' queries.
Or if your datagridview is the ONLY source for your data then you can delete all your previous data in your database and make one insert call for all of your datagridview data.
Try this:
using (SqlConnection cn = new SqlConnection())
{
cn.ConnectionString = "MyConnection" ;
cn.Open();
SqlDataAdapter da = new SqlDataAdapter();
DataTable dt = new DataTable();
using (SqlCommand cmd_select = new SqlCommand())
{
cmd_select.Connection = cn; cmd_select.CommandType = CommandType.StoredProcedure; cmd_select.CommandText = "clients_balances_select_glid_date";
da.SelectCommand = cmd_select;
da.Fill(dt);
for (int i = 0; i < dgv_balance.RowCount; i++)
{
if(/* check here if dt contains this row*/)
{
// Insert
}
else
{
// Update
}
}
}
}
I think you should insert or update all data one time.
Create index for glId column. If glId is primary key, it's indexed.
Assumes that List ClientBalance is list items you need update or insert.
public class ClientBalance
{
GlId int {get;set;}
ClientName string {get;set;}
Balance decimal {get;set;}
DateInput DateTime {get;set;}
}
You could serialize list Item to xml string and pass it to store procedure
public string Serialize<T>(T value) where T : new()
{
var serializeXml = string.Empty;
if (value != null)
{
try
{
var xmlserializer = new XmlSerializer(typeof(T));
var stringWriter = new StringWriter();
var writer = XmlWriter.Create(stringWriter);
xmlserializer.Serialize(writer, value);
serializeXml = stringWriter.ToString();
writer.Close();
}
catch (Exception ex)
{
return string.Empty;
}
}
return serializeXml;
}
Create a new store procedure for insert or update item like that:
CREATE PROCEDURE [dbo].[clients_balances_insert_or_update]
(
#xmlObject nvarchar(max)
)
AS
BEGIN
-- TABLE INCLUDE DATE FROM XML
DECLARE #tblBalances AS TABLE
(
GlId int,
DateInput datetime,
ClientName nvarchar(50),
Balance decimal(18,2)
)
DECLARE #idoc int -- xml id
-- PARSE XML TO OBJECT
EXEC sp_xml_preparedocument #idoc OUTPUT, #xmlObject
INSERT INTO #tblBalances
(
GlId, DateInput, ClientName, Balance
)
SELECT s.GlId, s.DateInput, s.ClientName, s.Balance
FROM OPENXML (#idoc, '/ArrayOfClientBalance/ClientBalance', 8) WITH (
GlId int 'GlId',
DateInput datetime 'DateInput',
ClientName NVARCHAR(50) 'ClientName',
Balance DECIMAL(18,2) 'Balance'
) s
EXEC sp_xml_removedocument #idoc
-- USE MERGE FOR INSERT OR UPDATE DATE
-- Use transaction
BEGIN TRAN InsertOrUpdate
BEGIN TRY
MERGE Target AS T
USING #tblBalances AS S
ON (T.GlId = S.GlId)
WHEN NOT MATCHED BY TARGET
THEN INSERT( GlId, DateInput, ClientName, Balance) VALUES( GlId, DateInput, ClientName, Balance)
WHEN MATCHED
THEN UPDATE SET DateInput = S.DateInput, Balance = s.Balance
COMMIT TRAN InsertOrUpdate;
END TRY
BEGIN CATCH
ROLLBACK TRAN InsertOrUpdate;
THROW;
END CATCH
END
Hope this helpfully!

SqlDbType.Structured to pass Table-Valued Parameters in NHibernate to select without a :param?

I want to pass a collection of IDs (via table-valued parameter) to an NHibernate IQuery select statement to be used in a join:
In native SQL, I can do this (SQLSelectData below). Notice there is no :param in the SqlCommand sql:
public static bool SQLSelectData()
{
string conACME = System.Configuration.ConfigurationManager
.AppSettings["conACME"].ToString();
DataTable tblBusUnit = new DataTable();
tblBusUnit.Columns.Add("VALUE", typeof(int));
DataRow dRow = tblBusUnit.NewRow();
dRow["Value"] = 1;
tblBusUnit.Rows.Add(dRow);
dRow = tblBusUnit.NewRow();
dRow["Value"] = 6;
tblBusUnit.Rows.Add(dRow);
using (SqlConnection con = new SqlConnection(conACME))
{
con.Open();
SqlDataReader rdr;
SqlCommand cmd = new SqlCommand(
"select bus_unit_id, BusUnit " +
"from BusUnit b " +
"join #tvpBusUnit s on s.value = b.BUS_UNIT_ID;",
con);
cmd.Parameters.Add(
new SqlParameter()
{
ParameterName = "#tvpBusUnit",
SqlDbType = SqlDbType.Structured,
TypeName = "dbo.[DLTableTypeInt]",
Value = tblBusUnit
});
rdr = cmd.ExecuteReader();
while (rdr.Read())
{
string stBusUnitId = rdr["bus_unit_id"].ToString();
string strBusUnit = rdr["BusUnit"].ToString();
Console.WriteLine("Bus Unit:" + strBusUnit);
}
}
return true;
}
How do I do this in NHibernate? I tried the accepted solution of this question by using the Sql2008Structured and Structured2008Extensions classes.
See code below that calls the SetStructured():
public void SQLSelectTVP<T>()
{
objNSession = NHibernateHelper.GetCurrentSession(strConn);
DataTable tblBusUnit = new DataTable();
tblBusUnit.Columns.Add("VALUE", typeof(int));
DataRow dRow = tblBusUnit.NewRow();
dRow["Value"] = 1;
tblBusUnit.Rows.Add(dRow);
dRow = tblBusUnit.NewRow();
dRow["Value"] = 6;
tblBusUnit.Rows.Add(dRow);
StringBuilder sbSQL = new StringBuilder();
sbSQL.Length = 0;
sbSQL.Append("select bus_unit_id, Business_Unit " +
"from tblBUSINESS_UNIT b " +
"join #tvpBusUnit s on s.value = b.BUS_UNIT_ID");
IQuery sqlQuery = objNSession.CreateSQLQuery(sbSQL.ToString());
sqlQuery.SetStructured("tvpBusUnit", tblBusUnit);
var lstQR = sqlQuery.List<T>();
}
However, it errors because there is no :param in the SQL:
Parameter tvpBusUnit does not exist as a named parameter in [select bus_unit_id, Business_Unit from tblBUSINESS_UNIT b join #tvpBusUnit s on s.value = b.BUS_UNIT_ID]
How can I fix this?
From the link you posted, I think the way you are accessing the structured variable is incorrect.
s.CreateSQLQuery("EXEC some_sp #id = :id, #par1 = :par1")
.SetStructured("id", dt)
Your code does not use the :id part, that is, :tvpBusUnit.
Also note that the TableType (in TypeName) may have to be created on the DB beforehand. Please check if this is required. From your code:
TypeName = "dbo.[DLTableTypeInt]",
Some discussion on passing table value parameters is provided here but NHibernate has an update without having to create types like this:
Passing table valued parameters to NHibernate. But this may need a pull-request. The answer provided in the other post you referred to allows you to create such types, one for each TableType.

Procedure or function expects parameter '#OperatorName', which was not supplied

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

Sql Exception : Implicit conversion from data type datetime to int is not allowed. Use the CONVERT function to run this query

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();
}
}
}