How do I get a SP into a string? - asp.net

I Dont know how to get my stored Procedures value into a String.
This is my guess but dosent work:
string id = Request.QueryString["ProductID"];
String Color = GetColor(id);
The GetColor(id) should be blue, but is "", and my String Color is "".
public static DataTable GetColor(string ProductID)
{
DbCommand comm = GenericDataAccess.CreateCommand();
comm.CommandText = "GetColor";
DbParameter param = comm.CreateParameter();
param.ParameterName = "#ProductID";
param.Value = ProductID;
param.DbType = DbType.Int32;
comm.Parameters.Add(param);
DataTable table = GenericDataAccess.ExecuteSelectCommand(comm);
return table;
}
ALTER PROCEDURE GetColor
#ProductID INT AS Select Color from tblColor where ProductID = #ProductID

I would guess that it's because your method is returning a DataTable, which doesn't cast directly to a string. I think something like GetColor(id).Rows[0][0] would work?

You should probably use ExecuteScalar here -- no reason at all to create a datatable to get a single value.

Can you set a breakpoint at return table; and inspected the returned result.
If the table is filled correctly then you will need to use
String Color = GetColor(id).Rows[0][0];
For your comment:
DataTable result = GetColor(id);
string Color = result.Rows[0][0];
string Price = result.Rows[0][1];
string Width = result.Rows[0][2];
But you need to inspect the result DataTable and its first row to make sure you have populated it correctly. Try to inspect result.Rows[0] in the quick watch window

Related

How to pass SqlCommand parameter dynamically using ASP.NET

I have created a class, in which I am trying to pass query and return the data in a DataTable, but I am unable to pass a parameter to the SqlCommand.
My attempt:
OpenSqlConnection();
SqlCommand sqlCommand = new SqlCommand(inputQuery, sqlConnection);
sqlCommand.CommandType = CommandType.StoredProcedure;
sqlCommand.Parameters.AddWithValue("", "");
sqlCommand.ExecuteNonQuery();
DataTable dtResult = new DataTable();
SqlDataAdapter da = new SqlDataAdapter(sqlCommand);
da.Fill(dtResult);
CloseSqlConnection();
return dtResult;
In the above code, I am passing SqlCommand as an input query.
How I am calling the above function.
stdFetchDt = new DBManager().GetRecordsByQuery("storedprocedurename");
stdDrop.DataSource = stdFetchDt;
stdDrop.DataBind();
Here DBManager is the class name and GetRecordsByQuery is the method name.
But I'm not able to pass value for sqlCommand.Parameters.AddWithValue("", "");.
My problem: I am unable to pass value in sqlCommand.Parameters.AddWithValue("", "");, because number of value may be multiple.
Please help me with this.
You can send your parameter string with values combined with ',' in C# and then separate theme in the stored procedure :
DECLARE #tags NVARCHAR(400) = 'clothing,road,,touring,bike'
SELECT value
FROM STRING_SPLIT(#tags, ',')
I have Created a class and passing OBJECT & VALUE using List argument.
public DataTable GetRecordsByQuery(string inputQuery, List<string> objectInput, List<string> valInput)
Here in inputQuery String, I am passing name of stored procedure and in objectInput passing object and in valInput passing its value.

Error converting nvarchar to int in ExecuteNonQuery

I am getting an error for the following program in asp.net.
I have checked sql and name is in nvarchar.
{
con.Open();
SqlCommand cmd = new SqlCommand("bookinsertion2", con);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#idnumber",txtid.Text);
cmd.Parameters.AddWithValue("#name", txtname.Text);
cmd.Parameters.AddWithValue("#year", txtyear.Text);
cmd.Parameters.AddWithValue("#department", txtdepart.Text);
cmd.Parameters.AddWithValue("#bookname", ddlbookavail.SelectedItem.ToString());
cmd.ExecuteNonQuery();
con.Close();
Response.Redirect("~/LendingForm2.aspx");
}
This is the code of the stored procedure
create Procedure [dbo].[bookinsertion2]
#idnumber int,
#name nvarchar(20),
#year int,
#department nvarchar(30),
#bookname nvarchar(25)
as
Begin
insert into tbllendinginfo values(#idnumber,#name,#year,#department,#bookname)
insert into tbllendinginfo(Dateofbooktaken) values(GETDATE())
update tblbookinfo set BooksAvailable=BooksAvailable-(select COUNT(Id) from tbllendinginfo where BookName=#bookname) where Name=#bookname
end
The error is " Conversion failed when converting the nvarchar value 'Mike' to data type int. "
The error message is clear, one or more of the parameters expected by the stored procedure are not of type nvarchar. Probably the #year and #idnumber parameters are an integers. If that's true then you need to call
cmd.Parameters.AddWithValue("#idnumber",Convert.ToInt32(txtid.Text));
cmd.Parameters.AddWithValue("#year", Convert.ToInt32(txtyear.Text));
Said that, please try, if possible to avoid the call to AddWithValue, in particular in case where strings or date are involved. AddWithValue determines the type of the parameter from the input value and most of the time is correct, but there are situations where it decides for a wrong datatype and the errors are difficult to find. Moreover AddWithValue with strings is a performance hurdle.
A better explanation could be found in these two articles.
Can we stop using AddWithValue() already?
How Data Access Code Affects Database Performance
You could rewrite the code above using the Object Initializer Syntax
{
con.Open();
SqlCommand cmd = new SqlCommand("bookinsertion2", con);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.Add(
new SqlParameter
{
ParameterName = "#idnumber",
SqlDbType = SqlDbType.Int,
Value = Convert.ToInt32(txtid.Text)
});
cmd.Parameters.Add(
new SqlParameter
{
ParameterName = "#name",
SqlDbType = SqlDbType.NVarChar,
Size = 50,
Value = txtname.Text
});
cmd.Parameters.Add(
new SqlParameter
{
ParameterName = "#year",
SqlDbType = SqlDbType.Int,
Value = Convert.ToInt32(txtyear.Text)
});
cmd.Parameters.Add(
new SqlParameter
{
ParameterName = "#department",
SqlDbType = SqlDbType.NVarChar,
Size = 50,
Value = txtdepart.Text
});
cmd.Parameters.Add(
new SqlParameter
{
ParameterName = "#bookname",
SqlDbType = SqlDbType.NVarChar,
Size = 50,
Value = ddlbookavail.SelectedItem.ToString()
});
cmd.ExecuteNonQuery();
con.Close();
Response.Redirect("~/LendingForm2.aspx");
}
EDIT
After your edit I think the problem is in this line of the stored procedure:
insert into tbllendinginfo values(#idnumber,#name,#year,#department,#bookname)
You haven't specified the columns' names but just the parameters. So the server inserts the parameter following the order of definition of the columns in the datatable.
Of course, if the second column in the table is not the column that should receive the #name parameter you could have serious problems.
You could fix the problem listing the name of the columns in the same order iun which you put the parameter inside the VALUES clause or changing the order of the parameters to follow the order of the column names.
For example (I don't know the column names so you should fix them)
insert into tbllendinginfo (idnumber, name, bookyear, department, bookname)
values(#idnumber,#name,#year,#department,#bookname)

What is wrong with the following query?

I have a table containing name, surname and email. I want to retrieve them from the table and so i write:
if (LoginAs.SelectedValue == "Administrator")
{
string result;
string query = "Select * from AdminTable where ID='"+ idBox.Text +"'";
cmd1 = new SqlCommand(query, con);
result = Convert.ToString(cmd1.ExecuteScalar());
Response.Redirect("Admin.aspx");
//Admin user = new Admin(idBox.Text, "Active", mail, firstName, LastName, passwordBox.Text);
}
The problem is, it only returns the name field of the specified row even though i wrote "Select *". What is wrong here?
ExecuteScalar returns just the first column of the first row, and ignores the rest.
So you should use ExecuteReader method. An example from MSDN:
using (SqlConnection connection = new SqlConnection(
connectionString))
{
connection.Open();
SqlCommand command = new SqlCommand(queryString, connection);
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
Console.WriteLine(String.Format("{0}", reader[0]));
}
}
Note that the while (reader.Read()) checks whether your query returned (more) results and positions the cursor on the next record, that you can then read. This example prints the first column's value.
The using statement makes sure the connection is closed after use, whatever happens.
Also, don't build your query directly with input from the user (such as the value of a TextBox), use parameters instead to prevent SQL injection attacks.
You must try ExecuteReader() instead of using ExecuteScalar()
ExecuteScaler is used in situation where we have to read a single value.eg:
select count(*) from tablename.
while
ExecuteReader is used for any result set with multiple rows/columns
(e.g., SELECT * from TableName)
Sample code:
string myQuery="Select * from AdminTable where ID=#myid";
SqlCommand cmd=new SqlCommand(myQuery,conn);
cmd.Parameters.AddWithValue("#myid", value);
conn.Open();
SqlDataReader dreader;
dreader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
while (dreader.Read())
{
string Value1= dreader["COl1"].ToString();
string Value2= dreader["COl2"].ToString();
}
dreader.Close();
Always use parameterized Query
You may try cmd1.ExecuteReader() instead.

System.Data.SqlClient.SqlException: Invalid column name

Trying to do a recordset, I just want one column of data, but this code is giving me an error.. I'm an ASP.NET newb, can anyone help?:
System.Data.SqlClient.SqlException: Invalid column name
'CustomerName'.
using (SqlConnection con = new SqlConnection(DB.GetDBConn()))
{
con.Open();
using (IDataReader dr = DB.GetRS("select CustomerName from Customer where CustomerID=" + Customer.CustomerID, con))
{
string CustomerName = "CustomerName";
}
}
String EncCustomerName = Encrypt(CustomerName.Replace(".", "").Replace("-", ""),"1");
Question #2: How do I bind the database content to the CustomerName string? It seems like its only returning "CustomerName" as the value for CustomerName string.. I would like it to return the database data for CustomerName string.. Help?
Suggested to use a ExecuteScalar, so i modified the request to this
using (var con = new SqlConnection(DB.GetDBConn()))
using (var cmdContrib = new SqlCommand("SELECT CustomerName FROM Customer WHERE CustomerID=" + ThisCustomer.CustomerID, con))
{
con.Open();
string CustomerName = cmdContrib.ExecuteScalar();
}
And i Get this error:
"string CustomerName = cmdCust.ExecuteScalar();"
CS0266: Cannot implicitly convert type 'object' to 'string'. An explicit conversion exists (are you missing a cast?)
To answer your second question:
// Set it here so you can access it outside the scope of the using statement
string CustomerName = "";
using (SqlConnection con = new SqlConnection(DB.GetDBConn()))
{
con.Open();
using (IDataReader dr = DB.GetRS("select CustomerName from Customer where CustomerID=" + Customer.CustomerID, con))
{
while (dr.Read())
CustomerName = dr["CustomerName"].ToString();
}
}
}
If you're sure you'll only get one CustomerName result, using a DataReader is a bit of an overkill.
SqlCommand.ExecuteScalar Example
string CustomerName = "";
using (SqlConnection con = new SqlConnection(DB.GetDBConn()))
{
SqlCommand cmd = new SqlCommand("SELECT CustomerName FROM Customer WHERE CustomerID = " + Customer.CustomerID, con);
cmd.CommandType = CommandType.Text;
con.Open();
CustomerName = Convert.ToString(cmd.ExecuteScalar());
}
SqlCommand.ExecuteScalar Method
Additional Info
ExecuteScalar returns an object, so you'll need to convert the returned value to the proper type (in this case, string).
Also, you should declare your CustomerName value outside of the using blocks (as I did in my example) - otherwise it will be scoped to the using blocks and not available outside of them.
It means that either CustomerName or CustomerID is not a valid column within your database. Check your table again.
Make sure you are trying to connect correct database.
See CustomerName column should be in Customer table. check spelling also
First, debug and check the value of:
DB.GetDBConn()
You will verify that you are going to the same in Studio as you are in the program.
I think it is the spelling somewhere between the db and your code.
Once you get past the error, you need to fix this:
{
string CustomerName = "CustomerName";
}
You are not accessing the reader, try some kind of tutorial for that stuff.
Try doing a select * from customer where ... and put a breakpoint on your using datareader statement. Then use quick-watch on the datareader object to investigate the columns exposed in the recordset.
Or you could run the select statement on your db of choice to ensure that the column name is the same.
I agree with Madhur above, your column name is not spelled correctly. Or you are not connecting to the correct db.
Hope this helps

How to get output parameter of sql in codebehind

My stored procedure is like this.
ALTER PROCEDURE [dbo].[GetImagesByDesignId]
#DesignID bigint,
#RegID bigint,
#PageIndex INT,
#NumRows INT,
#ImageCount INT OUTPUT
AS
BEGIN
SELECT #ImageCount=(SELECT COUNT(*) FROM DocManagement where DesignID=#DesignID and RegID=#RegID)
Declare #startRowIndex INT;
set #startRowIndex = (#PageIndex * #NumRows) + 1;
With ImageEntries as (
SELECT ROW_NUMBER() OVER (ORDER BY DocumentID ASC) as Row, RegID, DesignID,ImageName
FROM DocManagement
WHERE DesignID=#DesignID and RegID=#RegID
)
Select RegID, DesignID,ImageName
FROM ImageEntries
WHERE Row between
#startRowIndex and #StartRowIndex+#NumRows-1
END
I am calling storedprocedure in my codebehind as
Dim dt As DataTable = objUpload.GetDocuments(lngRegID, lngDesignID)
dlView.DataSource = dt
dlView.DataBind()
dlView is datalist.Method GetDocuments is written in another class like this
Public Function GetDocuments(ByVal lngRegID As Long, ByVal lngDesID As Long) As DataTable
Try
Dim db As Database = DatabaseFactory.CreateDatabase()
Dim DbCommand As DbCommand = db.GetStoredProcCommand("GetImagesByDesignId")
db.AddInParameter(DbCommand, "#RegID", DbType.Int64, lngRegID)
db.AddInParameter(DbCommand, "#DesignID", DbType.Int64, lngDesID)
db.AddInParameter(DbCommand, "#PageIndex ", DbType.Int32, intPageIndex)
db.AddInParameter(DbCommand, "#NumRows ", DbType.Int32, intNumRows)
db.AddOutParameter(DbCommand, "ImageCount", DbType.Int32, 250)
Return db.ExecuteDataSet(DbCommand).Tables(0)
Dim strOutput() As String = {db.GetParameterValue(DbCommand, "ImageCount").ToString}
Catch ex As Exception
End Try
End Function
Problem is i want to get datattable as well as imagecount in codebehind.How can i return back datatable and imagecount to codebehind.Can anybody help?
You can create a class to use are return value that holds both the data table and the image count. Or you can send a variable as an argument by reference:
Public Function GetDocuments(ByVal regID As Long, ByVal desID As Long, ByRef imageCount As Integer) As DataTable
In the method you just set the value of imageCount.
In your stored procedure you don't need a nested query to get the count. Just do like this:
select #ImageCount = count(*)
from DocManagement
where DesignID = #DesignID and RegID = #RegID
Note:
I see that you have a Catch block without anything in it. Never ever do that. You are catching exceptions and ignoring them, that can only lead to problems.
In there rare case where you actually need to catch an exception and ignore it, you should at least have a comment inside the Catch block explaining why it's ignored.
Also, you are catching the base class Exception, when you should catch a more specific class like SqlException.
Public Function GetDocuments(ByVal lngRegID As Long, ByVal lngDesID As Long, ByRef strOutput As String) As DataTable
You can use ByRef and pass a string variable as a reference and set it in your method. The reference of strOutput will be passed to your method, and when you set the value of that variable in the method you can get back the changed value after the method call.
Dim strOutput As String = Nothing
Dim dt As DataTable = GetDocuments(lngRegID, lngDesID, strOutput)
Console.WriteLine(strOutput)

Resources