How to pass parameter to Dataset for query using c# - c#

I want to change SQL statement in DataSet for adding where query
where LogTime between #parameter1 and #parameter2
how can I pass parameter DateStr and DateEnd to #parameter1 and #parameter2
from c# method
DataSet1 ds = new DataSet1();
I guess We should Using DataTable1TableAdapter from DataSet1
Is any suggested way to Implement it ?
We got these query in DataTable1TableAdapter already
SELECT IPassLog.ParkID, ParkInfo.ParkName, IPassLog.UserID, IPassLog.LogTime, IPassLog.LogInTime, IPassLog.InitBalance,
IPassLog.TranAmount, IPassLog.TranBalance, IPassLog.CheckDone, IPassLog.TranSN, IPassLog.PackName, IPassLog.ResultName, IPassLog.SettlementDate,
IPass_Result_Hex.Result_Desc, IPass_ErrorCode.Explanation
FROM IPassLog INNER JOIN ParkInfo ON IPassLog.ParkID = ParkInfo.ParkID
FULL JOIN IPass_Result_Hex ON IPassLog.VerifyResult = IPass_Result_Hex.Result_Hex FULL JOIN IPass_ErrorCode ON IPassLog.VerifyFlag = IPass_ErrorCode.Code;
and I want add where statement into these query

You can make use of the SqlDataAdapter class's constructor that accept SqlCommand as parameter. So that you can pass the parameterized command to this class to create the instance of SqlDataAdapter
I prefer you to use like thi:
string connectionString = "your connection string here";
string query = "select blah, foo from mytable where LogTime >= #parameter1 and LogTime<= #parameter2";
DataSet ds = new DataSet();
using (SqlCommand cmd = new SqlCommand(query, new SqlConnection(connectionString)))
{
cmd.Parameters.Add("parameter1", SqlDbType.DateTime).Value = dateInput1;
cmd.Parameters.Add("parameter2", SqlDbType.DateTime).Value = dateInput2;
using (SqlDataAdapter adapter = new SqlDataAdapter(cmd)) {
adapter.Fill(ds);
}
}

follow the post : Tutorial 1: Creating a Data Access Layer which talks about how to deal with parameter in table adapter query. it also provide code example for the same.
if you can to pass parameter to your query then create parameter like this
SqlParameter param= new SqlParameter();
param.ParameterName = "#parameter1";// Defining Name
param.SqlDbType = SqlDbType.Int; // Defining DataType
param.Direction = ParameterDirection.Input; // Setting the direction
param.Value = inputvalue;
and add created parameter to your command object
// Adding Parameter instances to sqlcommand
comm.Parameters.Add(param);

Related

How to get output parameter and also a table when executing a stored procedure

Scenario
I'm working with SQL Server 2017 (not possible to change)
I'm using Visual Studio 2019 in C# console and .NET Framework 4.5 (possible to change)
I'm using ADO.NET because several years before we couldn't use Entity Framework, as the system is made to work with a stored procedure that returns at least 100k rows (possible to change)
Situation
I have an USP that returns a table that is at least 100k of rows by 20 fields. I need to add an output parameter in order to get also an ID created by the USP itself. So, the situation is that I need return a table and an ID (called ProcMonitorId). I don't know if this is even so possible (See workarounds section)
At the SQL level is seems to be so far so good:
CREATE PROCEDURE [myschema].[mystore]
#ProcMonitorId BIGINT OUTPUT
AS
BEGIN
BEGIN TRANSACTION
(...)
SELECT fields FROM myTable
SELECT #ProcMonitorId = #internalVariable
SQL execution:
And at repository layer (only relevant lines, someone were surprised for health of example):
var command = new SqlCommand("myStoreProcedure", mycon);
command.CommandType = CommandType.StoredProcedure;
SqlParameter outPutParameter = new SqlParameter();
outPutParameter.ParameterName = "#ProcMonitorId";
outPutParameter.SqlDbType = System.Data.SqlDbType.BigInt;
outPutParameter.Direction = System.Data.ParameterDirection.Output;
command.Parameters.Add(outPutParameter);
// Open connection etc-etc that works
SqlDataAdapter da = new SqlDataAdapter(command);
DataTable dt = new DataTable();
string ProcMonitorId = outPutParameter.Value.ToString();
da.Fill(dt);
Everything worked fine until the addition of the output at C# level. It returns in the line:
string ProcMonitorId = outPutParameter.Value.ToString();
it returns NullReferenceException because Value is null (that can't be) and of course, can't convert to String. I would solve this situation by adding a ? but if that's situation happens for real, I need catch it any way as error. The main idea is that Value can not be null.
As I don't have any ORM map, (and my expertise is not ADO.NET but Entity Framework) I can't understand why is null (No, is not null at SQL layer, always return a value)
Question
How can I solve this error or how can I return a BIGINT parameter and ALSO a table result?
Workarounds
As I first glance I have to solve it quickly, I made a:
SELECT 1 as type, #procID as procid, null as data1, null as data2
UNION ALL
SELECT 2 as type, null as procid, data1, data2
in order to simulate a "header" and "data" rows on one single table.
But I don't like this solution and is not very elegant and flexible. I've to parse the header every time.
Thanks in advance and please comment anything, tip, help, workaround, I will be glade to update my answer if more information is needed.
Also I can make my Framework to .NET Core or change to Entity Framework. That I can't change is my SQL version
Update #2
No changes in SQL - Still working as screenshot
In C# - Hangs out for ever
SqlConnection connection = new SqlConnection(ConfigurationManager.AppSettings["DbConnection"]);
connection.Open();
var command = new SqlCommand("myUSP", connection);
command.CommandType = CommandType.StoredProcedure;
command.CommandTimeout = Convert.ToInt16(ConfigurationManager.AppSettings["DataBaseTimeOut"]);
if (connection.State != ConnectionState.Open)
{
connection.Open();
}
SqlParameter r = command.Parameters.Add("#ProcMonitorId", SqlDbType.BigInt);
r.Direction = ParameterDirection.Output;
DataTable dt = new DataTable();
using (var rdr = command.ExecuteReader())
{
dt.Load(rdr);
long id = (long)r.Value;
}
SqlDataAdapter da = new SqlDataAdapter(command);
da.Fill(dt);
The parameter value won't be available until after you consume the resultset, eg
var cmd0 = new SqlCommand("create or alter procedure pFoo #id int output as begin select * from sys.objects; set #id = 12; end", con);
cmd0.ExecuteNonQuery();
var cmd = new SqlCommand("pFoo", con);
cmd.CommandType = CommandType.StoredProcedure;
var p1 = cmd.Parameters.Add("#id", SqlDbType.Int);
p1.Direction = ParameterDirection.Output;
var dt = new DataTable();
using (var rdr = cmd.ExecuteReader())
{
dt.Load(rdr);
var id = (int)p1.Value;
}
You should use a Parameter with the Direction property set to ReturnValue, and, inside the sp, declare an internal variable and set it to the value you want.
Then call the RETURN statement before leaving the StoredProcedure.
As an example, see this SP:
ALTER PROCEDURE [GetTimeZoneGMT]
#TimeZone NVARCHAR(128)
AS
BEGIN
DECLARE #timeZoneNumber as INT = -20;
IF #TimeZone ='Pacific/Midway'
SET #timeZoneNumber = -11
ELSE IF #TimeZone ='Pacific/Niue'
SET #timeZoneNumber = -11
ELSE IF #TimeZone ='Pacific/Pago_Pago'
SET #timeZoneNumber = -11
SELECT 1 -- or whatever you need to have as result set
RETURN #timeZoneNumber;
END
The stored procedure ends with a (bogus) SELECT statement but also has a RETURN statement with the parameter set inside the SP logic.
Now from the C# side you could call it in this way (LinqPad example)
using (var connection = new SqlConnection("Data Source=(LOCAL);Initial Catalog=LinqPADTest;Integrated Security=True;"))
{
connection.Open();
SqlCommand cmd = new SqlCommand("GetTimeZoneGMT", connection);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#TimeZone", SqlDbType.NVarChar).Value = "Asia/Kuala_Lumpur";
SqlParameter r = cmd.Parameters.Add("#p2", SqlDbType.BigInt);
r.Direction = ParameterDirection.ReturnValue;
DataTable dt = new DataTable();
dt.Load(cmd.ExecuteReader());
r.Value.Dump(); // Prints -20
dt.Dump(); // Prints a row with a single column with 1 as value
}

Must declare the scalar variable - SQL parameter for filling DataGridView

I found similar questions, but none of the answers have helped me or apply to me.
I'm using Visual Studio 2013, C# and database engine called T-SQL.
The SQL command works just fine if I replace the parameter with a concrete value. But I need the parameter there.
I get this error:
Must declare the scalar variable "#Collection1".
On this line:
myydata.Fill(myytab);
No matter what I do, that #Collection1 just doesn't want to be declared.
string stringcommand = "select Name, Collection, Text from Card_List where Collection IN" +
"(select Shortcut from Collections where Collection Like #Collection1)";
SqlConnection myConnection = new SqlConnection(stringconnection);
SqlCommand myCommand = new SqlCommand(stringcommand, myConnection);
// Tried to declare parameter 5 times here, unsuccessfully
myCommand.Parameters.Add(new SqlParameter("Collection1", string1));
myCommand.Parameters.Add("#Collection1", SqlDbType.NVarChar).Value = string1;
myCommand.Parameters["#Collection1"].Value = string1;
myCommand.Parameters.AddWithValue("#Collection1", string1);
SqlParameter Param1 = myCommand.Parameters.Add("#Collection1", SqlDbType.NVarChar);
Param1.Value = string1;
SqlDataAdapter myydata = new SqlDataAdapter();
myydata.SelectCommand = new SqlCommand(stringcommand, myConnection);
myConnection.Open();
DataTable myytab = new DataTable();
myydata.Fill(myytab);
BindingSource bsour = new BindingSource();
bsour.DataSource = myytab;
dataGridView1.DataSource = bsour;
myydata.Update(myytab);
myConnection.Close();
You want the SqlCommand myCommand you set up to be used as the myydata.SelectCommand, like:
myCommand.Parameters.Add(new SqlParameter("Collection1", string1));
myydata.SelectCommand = myCommand;
The way you have it with myydata.SelectCommand = new SqlCommand(stringcommand, myConnection);, that command has the #Collection1 in the command, but without having any parameters attached you get the Must declare the scalar variable "#Collection1". error.

Library catalog search sql statement

I want the user to select the search criteria for his books here is code, suggestions please!!
String keyword=Textbox1.Text; //User types keyword
String userCriteria=Textbox2.Text;// Can be Title, Author, Subject or ISBN;
String sql="Select * from tableBooks WHERE '"+keyword+"' like '%"+userCriteria+"'%";
How to let the user select their own criteria for searching the database?
You certainly need a better way to build your query.
You do not directly take input from the user without certain measure of checking or filtering and put it in your query. That would expose your application to sql injections.
Use SQL parameters.
Try this link as reference :http://www.dotnetperls.com/sqlparameter
example :
using (SqlCommand command = new SqlCommand("Select * from tableBooks WHERE #Field LIKE #Value", connection))
{
//
// Add new SqlParameter to the command.
//
command.Parameters.Add(new SqlParameter("Field", Textbox1.Text)); // I do not recommend using a textbox and letting the user write anything. You have to limit his choices by the fields in your table. Use a dropdownlist and limit his choices by meaningful fields in your "tableBooks" table.
command.Parameters.Add(new SqlParameter("Value", Textbox2.Text));
//
// Read in the SELECT results.
//
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
//GET YOUR BOOK
}
}
Please notice my comments :
// I do not recommend using a textbox and letting the user write anything as a "keyword". You have to limit his choices by the columns in your table. Use a dropdownlist and limit his choices by meaningful choices from your "tableBooks" table.
It is more secure to used parameterized query than the form you use already
you can try this, I think it will help
// Declare a connection
conn = new
SqlConnection("Server=.;DataBase=DataBase;Integrated Security=SSPI");
conn.Open();
//Create parameterized query
SqlCommand cmd = new SqlCommand(
"Select * from tableBooks WHERE (case #userCriteria when 'Title' then Title when 'Author' then Author when 'Subject' then Subject when 'ISBN' then ISBN else '' end) LIKE '%'+#keyword+ '%'", conn);
//Create parameter userCriteria
SqlParameter param = new SqlParameter();
param.ParameterName = "#userCriteria";
param.Value = userCriteria;
//Create parameter keyword
SqlParameter param = new SqlParameter();
param.ParameterName = "#keyword";
param.Value = userCriteria;
// add new parameter to command object
cmd.Parameters.Add(param);
// get data stream
reader = cmd.ExecuteReader();
// write each record
while(reader.Read())
{
//Get data
}

Procedure or function expects parameter, which was not supplied

I am calling a simple stored procedure written in SQL Server 2008 with parameter from c# but it display error
"Procedure or function 'AddYear' expects parameter '#mYear', which was not supplied."
What's wrong with this code, i tried several things but didn't successed.
SqlCommand AddEquip = new SqlCommand("AddYear", dbConn);
SqlDataReader rdrEquip;
SqlParameter mP = new SqlParameter("#mYear",SqlDbType.VarChar ) ;
mP.Value = "1990";
AddEquip.Parameters.Add(mP);
rdrEquip = AddEquip.ExecuteReader();
-- Parameter Name & type are the same i use in the Procedure.
Seems like you forgot to set the SqlCommand as stored-procedure:
SqlCommand AddEquip = new SqlCommand("AddYear", dbConn);
AddEquip.CommandType = CommandType.StoredProcedure;
You need to add the parameter to your SqlParameter e.g:
mP = new SqlParameter("#mYear", SqlDbType.VarChar, PARAMETER_HERE);
if your Storedprocedure is expecting a parament than you have to pass it sqlcommand object
SqlParameter[] param = new SqlParameter[0];
param[0] = new SqlParameter("#mYear", "1990");
rdrEquip = SqlHelper.ExecuteReader(Con, CommandType.StoredProcedure, "SPC_proc", param);
i am using sqlhelper class here.

Can I indicate where my MySQL parameter should go more meaningfully than just having a ? to mark the position - using ODBC connectors and .NET

I've got a chunk of code where I can pass info into a MySQL command using parameters through an ODBC connection.
Example code showing surname passed in using string surnameToLookFor:
using (OdbcConnection DbConn = new OdbcConnection( connectToDB ))
{
OdbcDataAdapter cmd = new OdbcDataAdapter(
"SELECT Firstname, Address, Postcode FROM customers WHERE Surname = ?", DbConn);
OdbcParameter odbcParam = new OdbcParameter("surname", surnameToLookFor);
cmd.SelectCommand.Parameters.Add(odbcParam);
cmd.Fill(dsCustomers, "customers");
}
What I'd like to know is whether I can indicate where my parameter should go more meaningfully than just having a ? to mark the position - as I could see this getting quite hard to debug if there are multiple parameters being replaced.
I'd like to provide a name to the parameter in a manner something like this:
SELECT Firstname, Address, Postcode FROM customers WHERE Surname = ?surname ",
When I try this it just chokes.
The following code
public System.Data.DataSet Customer_Open(string sConnString, long ld)
{
using (MySqlConnection oConn = new MySqlConnection(sConnString))
{
oConn.Open();
MySqlCommand oCommand = oConn.CreateCommand();
oCommand.CommandText = "select * from cust_customer where id=?id";
MySqlParameter oParam = oCommand.Parameters.Add("?id", MySqlDbType.Int32);
oParam.Value = ld;
oCommand.Connection = oConn;
DataSet oDataSet = new DataSet();
MySqlDataAdapter oAdapter = new MySqlDataAdapter();
oAdapter.SelectCommand = oCommand;
oAdapter.Fill(oDataSet);
oConn.Close();
return oDataSet;
}
}
is from http://www.programmingado.net/a-389/MySQL-NET-parameters-in-query.aspx
and includes the fragment
where id=?id
Which would be ideal.
Is this only available through the .Net connector rather than the ODBC?
If it is possible to do using ODBC how would I need to change my code fragment to enable this?
It would be nice if ODBC had this feature but it doesn't, I'm afraid. I'm speaking of the C API itself here - I don't know if there is a C# layer that adds it. It's not too difficult to write your own wrapper function to implement a simple version of it though.

Categories

Resources