Assign value from stored procedure to a variable - c#

I'm using stored procedure to get the 'password' value from the database. and i need to assign this value to a variable. I'm using asp.net- mvc and Ado.net.
Here is my stored procedure.
CREATE PROCEDURE [dbo].[getPassword]
(
#Email VARCHAR(100)
)
AS
BEGIN
SELECT Password FROM dbo.Staff_Login WHERE Email=#Email
END
Here is my repository class.
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
namespace Job_Recuitment_System.Repository
{
public class LoginRepository
{
private SqlConnection con;
//To handle sql connection
private void connection() {
string constr = ConfigurationManager.ConnectionStrings["mycon"].ToString();
con = new SqlConnection(constr);
}
//to get the password
public List<StaffLogin> getPassword(StaffLogin obj) {
connection();
List<StaffLogin> pword = new List<StaffLogin>();
SqlCommand com = new SqlCommand("getPassword", con);
com.CommandType = CommandType.StoredProcedure;
com.Parameters.AddWithValue("#Email",obj.Email);
SqlDataAdapter da = new SqlDataAdapter(com);
DataTable dt = new DataTable();
con.Open();
da.Fill(dt);
con.Close();
//Bind StaffLogin
pword = (from DataRow dr in dt.Rows
select new StaffLogin()
{
Password = Convert.ToString(dr["Password"]),
}).ToList();
return pword;
}
}
}
I have use a list. But i need to assign value to a varible. because i only i need is one value (password).

You don't need an SqlDataAdapter but you just use the SqlCommand.ExecuteScalar
connection();
SqlCommand com = new SqlCommand("getPassword", con);
com.CommandType = CommandType.StoredProcedure;
com.Parameters.Add("#Email",SqlDbType.NVarChar, 100). Value = obj.Email;
con.Open();
var result = com.ExecuteScalar();
if(result != null)
MessageBox.Show("Password = " + result.ToString();
con.Close();
ExecuteScalar returns the first column of the first row retrieved by the command and your query fits nicely this condition. However it is important to consider that ExecuteScalar could return NULL if the query doesn't produce any result so always test the result against a null value before using it.
On another matter I really suggest you to avoid stored procedures for these simple menial tasks unless there is a good reason to use them. Using the Add instead of AddWithValue and specifying the exact size of the parameter gives to the Sql optimizer enough hints to create an optimized query.
Finally, remember that storing/returning passwords in clear text is considered a very big security risk. Try to use a safer method as explained in this question: Best way to store passwords in a database

In this case you are retrieving the value of a single column, You can use ExecuteScalar() in such situations. Then the command execution will be like the following:
string passwordStr= (string)com.ExecuteScalar();
So the signature of the getPassword method will also be changed, its return type will become string instead for List<StaffLogin>; the new signature will be:
public string getPassword(StaffLogin obj)
{
connection();
string passwordStr = String.Empty;
using (SqlCommand com = new SqlCommand("getPassword", con))
{
com.CommandType = CommandType.StoredProcedure;
com.Parameters.AddWithValue("#Email", obj.Email);
passwordStr = (string)com.ExecuteScalar();
}
return passwordStr;
}

Related

How to use C# connect to mysql and get json data?

As mentioned above:
I'm using C# to connect to a MySQL database and I want to read JSON data type.
I use the method MySqlCommand.ExecuteReader:
using (MySqlConnection sconn = new MySqlConnection(sqlConnectString))
{
sconn.Open();
String sql_Command = #"SELECT `id` FROM orders.jsontest;";
using (MySqlCommand scmd = new MySqlCommand(sql_Command, sconn))
{
**MySqlDataReader sdr = scmd.ExecuteReader();** // fatal error
DataTable datatable = new DataTable();
// ...
}
}
Can it be that I cannot use ExecuteReader here?
I know this question is old, but just in case you do not yet have a solution to your problem or anyone else encounters a similar problem, the following code should work for you:
private IEnumerable<int> GetIds()
{
using (MySqlConnection connection = new MySqlConnection(connectionString))
{
connection.Open();
string commandText = #"SELECT id FROM jsontest"; // Assuming that `orders` is your database, then you do not need to specify it here.
using (MySqlCommand command = new MySqlCommand(commandText, connection))
{
MySqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
yield return reader.GetInt32(0);
}
}
}
}
Now what you should pay attention to is this line
while (reader.Read())
which fetches results from the jsontest table as long as the MySqlDataReader can still read valid results and this line
yield return reader.GetInt32(0);
which instructs the reader to get and return each record of the fetched table one at a time as an Int32 (int). You need to change this if your tables column type is not INT.
Since you selected just one column (i.e. "SELECT id"), the parameter is 0, because your fetched resul table consists of one column only.
Additionally, in your code you seem to want to get the results as a DataTable; if so, you should use MySqlDataAdapter instead of the MySqlDataReader as follows:
DataTable resultTable = new DataTable("ResultTable");
MySqlDataAdapter adapter = new MySqlDataAdapter(command);
adapter.Fill(table);
Correct your sql command
String sql_Command = #"SELECT id FROM orders.jsontest";

How to get the result of an "EXEC storedProcedure()" in C#

Don't ask me why, but I want put in an sqlCommand object something like this:
sqlConnection a = new sqlConection(...);
sqlCommand b = new sqlCommand("EXEC storedProcedure()", a);
sqlDataAdapter c = new sqlDataAdapter(b);
DataTable d = new DataTable();
c.Fill(d);
So, when the stored procedure makes an insert the row is successfully added but however the code throws an Exception.
I know exist an sqlCommand.CommandType specifically for stored procedures but my architecture need it made in this way.
set the adapter "SelectCommand" property instead
var cmd = new SqlCommand("EXEC storedProcedure()", a);
cmd.CommandType = CommandType.StoredProcedure; //set command property
//..
var adapter = new SqlDataAdapter();
adapter.SelectCommand = cmd; //set adapter command for select query
and your command type must be CommandType.StoredProcedure to exec SP and your architecture don't need this? simply ask him for a good reason.
Your SQL syntax is off.
From http://technet.microsoft.com/en-us/library/ms188332.aspx :
USE AdventureWorks2012;
GO
DECLARE #CheckDate datetime;
SET #CheckDate = GETDATE();
EXEC dbo.uspGetWhereUsedProductID 819, #CheckDate;
GO
So your code should be:
new sqlCommand("EXEC storedProcedure", a);
While there are many ways to do the same thing, there are some things that work best when you do them the way the framework suggests.
In this case there are several things that can happen when you run the stored procedure, depending on which procedure it is. It might return a set of row, or several sets of rows, or nothing at all. There are already things we can do to handle all those situations, courtesy of the .NET framework.
Here's some extension code I've used in the past for any SP that is returning one or more rowsets:
public static DataSet ExecuteStoredProcedure(this SqlConnection connection, string SPName, params object[] parameters)
{
using (var cmd = connection.CreateCommand())
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = SPName;
cmd.CommandTimeout = 60;
if (connection.State != ConnectionState.Open)
connection.Open();
SqlCommandBuilder.DeriveParameters(cmd);
int index = 1;
foreach (object p in parameters)
{
if (index >= cmd.Parameters.Count)
break;
cmd.Parameters[index++].Value = (p == null ? DBNull.Value : p);
}
using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
{
DataSet res = new DataSet();
adapter.Fill(res);
return res;
}
}
}
Handling non-rowset return values and output parameters takes a bit more work, but this will do for your immediate needs:
var conn = new SqlConnection("some connection string");
DataSet ds = conn.ExecuteStoredProcedure("storedProcedure");
DataTable d = ds == null ? null : ds.Tables.Length < 1 ? null : ds.Tables[0];

Query & generic

I'm developing a C# solution with data access to Oracle.
And would like to have a generic solution about query.
Here is a part of my code :
public DataTable GetData(string query)
{
DbProviderFactory factory = DbProviderFactories.GetFactory("System.Data.OracleClient");
using (DbConnection conn = factory.CreateConnection())
{
try
{
DbConnectionStringBuilder csb = factory.CreateConnectionStringBuilder();
csb["Data Source"] = #"Northwind";
csb["User Id"] = #"Northwind";
csb["Password"] = #"Northwind";
conn.ConnectionString = csb.ConnectionString;
conn.Open();
using (DbCommand cmd = conn.CreateCommand())
{
cmd.CommandText = query;
using (DataTable dt = new DataTable())
{
DbDataAdapter da = factory.CreateDataAdapter();
cmd.CommandType = CommandType.Text;
da.SelectCommand = cmd;
da.Fill(dt);
return dt;
}
}
}
catch (Exception ex)
{
throw new Exception("Error", ex);
}
finally
{
if (conn.State != ConnectionState.Closed)
conn.Close();
}
}
}
And I call my method like this :
DataAccess.Provider data = new DataAccess.Provider();
DataTabel dt = dt.GetData("select * from myTable);
This works pretty good but this is not my aim.
I have a second class called CL_mpg with all my SQL queries.
class CL_MPG
{
public string rq_sql;
public string selectParam(string param)
{
this.rq_sql = "select * from myTable where id = '" + param + "';";
return this.rq_sql;
}
public string select()
{
this.rq_sql = "select * from myTable";
return this.rq_sql;
}
//...
}
And I would like to use my methods selectParam and/or select to fill my datatable, but I don't know how to do that.
Although others complain at your learning attempt, everyone has to start somewhere. Your method is actually an ok start, but I would change the parameter from a string to a DbCommand object. Then, you can create your methods to properly build the command and set proper parameters. Then pass the entire prepared command to your wrapper method (that creates connection, tests open successful, queries data, etc) and have your method return a DataTable object as you have... something like
public class CL_MPG
{
private DataTable GetData(DbCommand cmd )
{
// do all the same as you have with exception of your USING DBCOMMAND.
// just set the connection property of the incoming command to that of
// your connection created
// AT THIS PART --
// using (DbCommand cmd = conn.CreateCommand())
// {
// cmd.CommandText = query;
// just change to below and remove the closing curly bracket for using dbcommand
cmd.Connection = conn;
}
// Now, your generic methods that you want to expose for querying
// something like
public DataTable GetAllData()
{
DbCommand cmd = new DbCommand( "select * from YourTable" );
return GetData( cmd );
}
public DataTable GetUser( int someIDParameter )
{
DbCommand cmd = new DbCommand( "select * from YourTable where ID = #parmID" );
cmd.Parameters.Add( "#parmID", someIDParameter );
return GetData( cmd );
}
public DataTable FindByLastName( string someIDParameter )
{
DbCommand cmd = new DbCommand( "select * from YourTable where LastName like #parmTest" );
cmd.Parameters.Add( "#parmTest", someIDParameter );
return GetData( cmd );
}
}
Notice the command is being built and fully prepared and parameterized vs concatination of strings as prior comment was made which could expose you to SQL-injection. As for the parameters, and not querying Oracle, they may need to be tweaked some. Different engines use slightly different conventions. If connecting to SQL-Server database, it uses "#" to identify a parameter. In SyBase Advantage Database, it uses ":". Using Visual FoxPro, a simple "?" placeholder is used.
Also, if your query has many criteria, just keep adding additional "#parm" type placeholders, then add your parameters in the same order as they appear in your query just to make sure you didn't miss any. Some functions could have none, one or more based on your needs. Then, in the samples provided, its as simple as doing something like
DataTable whoIs = yourCL_MPGObject.GetUser( 23 );
if( whoIs.Rows.Count > 0 )
MessageBox.Show( whoIs.Rows[0]["WhateverColumnName"] );

How to create sql connection with c# code behind, access the sql server then conditionally redirect?

This is a question from an experienced beginner!
Using ASP.NET 4 C# AND SQL server,
I have a connection string in web.config to myDatabase named "myCS".
I have a database named myDB.
I have a table named myTable with a primary key named myPK
What are the NECESSARY lines of code behind (minimal code) to create a SQL connection, then select from myTable where myPK=="simpleText"
it will probably include:
sqlconnection conn = new sqlconnection(??? myCS)
string SQLcommand = select * from myDB.myTable where myPK==myTestString;
sqlCommand command = new SqlCommand(SQL,conn);
conn.Open();
booleanFlag = ????
conn.Close();
conn.Dispose();
then
If ( theAnswer != NULL ) // or (if flag)
{
Response.Redirect("Page1.aspx");
}
else
{
Response.Redirect("Page2.aspx");
}
Here is a limited simple tutorial:
First, you want to have a class to do the hard work for you, then you will use it with ease.
First, you have to crate the connection string in your web.config file and name it.
Here it is named DatabaseConnectionString, but you may named it myCS as required in the question.
Now, in App_Code create a new class file and name it SqlComm (this is just an example name) like:
using System;
using System.Data;
using System.Data.SqlClient;
using System.Web;
public class SqlComm
{
// this is a shortcut for your connection string
static string DatabaseConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["dbConStr"].ConnectionString;
// this is for just executing sql command with no value to return
public static void SqlExecute(string sql)
{
using (SqlConnection conn = new SqlConnection(DatabaseConnectionString))
{
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Connection.Open();
cmd.ExecuteNonQuery();
}
}
// with this you will be able to return a value
public static object SqlReturn(string sql)
{
using (SqlConnection conn = new SqlConnection(DatabaseConnectionString))
{
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
object result = (object)cmd.ExecuteScalar();
return result;
}
}
// with this you can retrieve an entire table or part of it
public static DataTable SqlDataTable(string sql)
{
using (SqlConnection conn = new SqlConnection(DatabaseConnectionString))
{
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Connection.Open();
DataTable TempTable = new DataTable();
TempTable.Load(cmd.ExecuteReader());
return TempTable;
}
}
// sooner or later you will probably use stored procedures.
// you can use this in order to execute a stored procedure with 1 parameter
// it will work for returning a value or just executing with no returns
public static object SqlStoredProcedure1Param(string StoredProcedure, string PrmName1, object Param1)
{
using (SqlConnection conn = new SqlConnection(DatabaseConnectionString))
{
SqlCommand cmd = new SqlCommand(StoredProcedure, conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter(PrmName1, Param1.ToString()));
cmd.Connection.Open();
object obj = new object();
obj = cmd.ExecuteScalar();
return obj;
}
}
}
Okay, this only a class, and now you should know how to use it:
If you wish to execute a command like delete, insert, update etc. use this:
SqlComm.SqlExecute("TRUNCATE TABLE Table1");
but if you need to retrieve a specific value from the database use this:
int myRequiredScalar = 0;
object obj = new object();
obj = SqlComm.SqlReturn("SELECT TOP 1 Col1 FROM Table1");
if (obj != null) myRequiredScalar = (int)obj;
You can retrieve a bunch of rows from the database this way (others like other ways)
This is relevant to your sepecific question
int Col1Value = 0;
DataTable dt = new DataTable();
dt = SqlComm.SqlDataTable("SELECT * FROM myTable WHERE myPK='simpleText'");
if (dt.Rows.Count == 0)
{
// do something if the query return no rows
// you may insert the relevant redirection you asked for
}
else
{
// Get the value of Col1 in the 3rd row (0 is the first row)
Col1Value = (int)dt.Rows[2]["Col1"];
// or just make the other redirection from your question
}
If you need to execute a stored procedure with or without returning a value back this is the way to do that (in this example there are no returning value)
SqlComm.SqlStoredProcedure1Param("TheStoredProcedureName", "TheParameterName", TheParameterValue);
Again, for your specific question return the table using the SqlDataTable , and redirect if dt.Rows.Count >0
Have fun.
There are many ways: LINQ, SqlDataReader, SQLDataAdapter, according to what you want to read (single value, datatable ...), so here is an example:
using (SqlConnection con = new SqlConnection("SomeConnectionString"))
{
var cmd = new SqlCommand("select from myTable where myPK==N'"+ simpleText+ "'",con);
cmd.Connection.Open();
var sqlReader = cmd.ExecuteReader();
while(sqlReader.Read())
{
//Fill some data like : string result = sqlReader("SomeFieldName");
}
sqlReader.Close();
cmd.Connection.Close();
cmd.Dispose();
}

Error in C# code

public void ExecStoredProc(string strprocName, SqlConnection sqlConnect, List<string> Paramvalues)
{
if (ConnectToDB() == true)
{
SqlCommand cmd = new SqlCommand(strprocName, sqlConnect);
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = strprocName;
SqlParameter parameters = new SqlParameter();
parameters.Value = Paramvalues;
cmd.ExecuteNonQuery();
}
}
This code is giving an error when I am passing the name of the procedure login which has two parameters,user and pwd. Though I am using the list to add parameters but it not not passed to the SP. Showing error in the line cmd.ExecuteNonQuery();
While you are declaring a new SqlParameter object you are not actually associating that object with cmd. Adding the below should help:
cmd.Parameters.Add(parameters)
You have to add sqlparamerter into cmd.Parameters
cmd.Parameters(new SqlParameter("Uid",value));
and no need to write CommandText.
cmd.Parameters.Add( new SqlParameter { ... }).Value = Paramvalues;
Other than the fact that you're not adding the parameter back to the command, you also have a list of strings as your parameter value. Your naming leads me to believe that each item in the list is a parameter. The way your code is at the moment, you're just creating one parameter (with no name).
You want something like this (except we don't know the parameter names):
foreach(string value in ParamValues)
{
cmd.Parameters.AddWithValue(/*ParamName*/, value);
}
If this is not the case and you want to pass the list of strings as a value for a single parameter then this question is more complicated and you need to clarify.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using Model = ObjectLibrary.Model;
using System.Configuration;
using System.Collections;
using System.Data;
public class Base
{
protected ArrayList Parameter = new ArrayList();
public DataTable FetchData(string spName)
{
//if you want to get it form app config else just hard code here
string connectionString = ConfigurationManager.AppSettings["ConnectionString"];
return ConnectToSql(connectionString, spName);
}
protected void ClearParameter()
{
Parameter.Clear();
}
protected void AddParameter(string parameterName, object value)
{
Parameter.Add(new SqlParameter(parameterName,value));
}
private DataTable ConnectToSql(string connection, string spName)
{
System.Data.SqlClient.SqlConnection conn;
conn = new System.Data.SqlClient.SqlConnection();
conn.ConnectionString = connection;
try
{
conn.Open();
SqlCommand sqlCommand = new SqlCommand(spName, conn);
sqlCommand.CommandType = CommandType.StoredProcedure;
sqlCommand.Parameters.AddRange(Parameter.ToArray());
SqlDataAdapter dataAdaptor = new SqlDataAdapter(sqlCommand);
DataTable dt = new DataTable();
dataAdaptor.Fill(dt);
conn.Close();
return dt;
}
catch (Exception ex)
{
throw ex;
}
finally
{
conn.Close();
}
}
}
You can use this class

Categories