Issues in insert function in SQL Server and C# - c#

C#:
protected void btnsearch_Click(object sender, EventArgs e)
{
SqlConnection con = Connection.DBconnection(); {
SqlCommand com = new SqlCommand("sp_studentresult", con);
com.CommandType = CommandType.StoredProcedure;
com.Parameters.AddWithValue("#id", textstudentid.Text);
com.Parameters.AddWithValue("#id_student", textstudentid.Text.Trim());
SqlParameter retval = new SqlParameter("#output", SqlDbType.VarChar, 50);
com.Parameters.AddWithValue("#tamil", txttamil.Text.Trim());
com.Parameters.AddWithValue("#english", txtenglish.Text.Trim());
com.Parameters.AddWithValue("#maths", txtmaths.Text.Trim());
com.Parameters.AddWithValue("#science", txtscience.Text.Trim());
com.Parameters.AddWithValue("#socialScience", txtsocialscience.Text.Trim());
retval.Direction = ParameterDirection.Output;
com.Parameters.Add(retval);
com.ExecuteNonQuery();
string Output = retval.Value.ToString();
textstudentid.Text = string.Empty;
txttamil.Text = string.Empty;
txtenglish.Text = string.Empty;
txtmaths.Text = string.Empty;
txtscience.Text = string.Empty;
txtsocialscience.Text = string.Empty;
SqlDataAdapter adp = new SqlDataAdapter(com);
DataSet ds = new DataSet();
adp.Fill(ds);
if (ds.Tables[0].Rows.Count > 0)
{
tblid.Visible = true;
txtid.Text = ds.Tables[0].Rows[0]["id"].ToString();
txttamil.Text = ds.Tables[0].Rows[0]["Tamil"].ToString();
txtenglish.Text = ds.Tables[0].Rows[0]["English"].ToString();
txtmaths.Text = ds.Tables[0].Rows[0]["Maths"].ToString();
txtscience.Text = ds.Tables[0].Rows[0]["Science"].ToString();
txtsocialscience.Text = ds.Tables[0].Rows[0]["SocialScience"].ToString();
}
else
{
tblid.Visible = false;
output.Text = Output;
}
}
What I have done:
Step 1
When I enter invalid id (which means id doesnot contain in student table) and search, it shows "doesn't exist".
Step 2
When I enter valid id (which means id contains in student and also contain in studentresult table) and search, it shows student marks, if I want to edit the marks and update, so it shows "marks updated".
Step 3
But when I enter id (which means id contains in student but doesn't contain in studentresult table) and search, it works updated function again with all the textboxes contains 0, instead it works insertion.
May I know, what my mistake in the above code?
Can anyone guide me?
I'm struggling for an hour, I'm beginner in .net.
Thanks,

sp_studentresult is broken: it should not insert into studentresult if there already is a row for the given id. Just add
AND NOT EXISTS (SELECT * FROM studentresult WHERE id_student=#id_student)
to
ELSE IF EXISTS (SELECT * FROM student WHERE id=#id_student)
Resulting to:
ALTER PROCEDURE sp_studentresult
(
#id int,
#output varchar(50) output,
#id_student varchar(50),
#Tamil Varchar (100),
#English varchar (50),
#Maths Varchar (50),
#Science Varchar (50),
#SocialScience Varchar (50)
)
AS
IF NOT EXISTS (SELECT * FROM student WHERE id=#id_student)
BEGIN
SET #output='Doesn not EXIST'
END
ELSE IF EXISTS (SELECT * FROM student WHERE id=#id_student)
AND NOT EXISTS (SELECT * FROM studentresult WHERE id_student=#id_student)
BEGIN
INSERT into studentresult (id_student,Tamil,English,Maths,Science,SocialScience) values (#id_student,#Tamil,#English,#Maths,#Science,#SocialScience)
SET #output='Inserted'
END
SELECT * from studentresult where id_student=#id

Related

how to get Stored Procedure output parameter in c#

I am trying to get the value of output parameter of a stored procedure in c# function. when i execute the SP i am getting correct result in sql server but i can't get in c#. Can you please tell me how can i get the output value in c#. Below is the function i am trying to get the output value in C# DAC.
public DataSet GetOrderItemPictureByOrderId(int orderID, int PageIndex)
{
DataSet dtOrder = new DataSet();
/// Connect to database.
Database db = DatabaseFactory.CreateDatabase(CONNECTION_NAME);
using (DbCommand cmd = db.GetStoredProcCommand("uspGetOrderItemPicturePageWise"))
{
/// Set parameter values.
db.AddInParameter(cmd, "#OrderID", DbType.Int32, orderID);
db.AddInParameter(cmd, "#PageIndex", DbType.Int32, PageIndex);
db.AddInParameter(cmd, "#PageSize", DbType.Int32, 6);
db.AddOutParameter(cmd, "#RecordCount", DbType.Int32, 4);
try
{
dtOrder = db.ExecuteDataSet(cmd);
string outputValue = cmd.Parameters["#RecordCount"].Value.ToString(); // here i want to get the output value and want to return the value to main code
}
catch (Exception ex)
{
LogErrors.WriteError(ex);
}
}
return dtOrder;
}
}
Here i am calling the function :-
DataSet _ds = _orderPicDAC.GetOrderItemPictureByOrderId(OrderID, PageIndex);
My Store Procedure :--
CREATE PROCEDURE [dbo].[uspGetOrderItemPicturePageWise]
#OrderID int,
#PageIndex INT = 1
,#PageSize INT = 10
,#RecordCount INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SELECT ROW_NUMBER() OVER
(
ORDER BY [PictureId] ASC
)AS RowNumber,
Orderid,
GenericFieldID,
ItemImage
INTO #Results
FROM [OrderPictures]
WHERE OrderID = #OrderID
SELECT #RecordCount = COUNT(*)
FROM #Results
SELECT * FROM #Results
WHERE RowNumber BETWEEN(#PageIndex -1) * #PageSize + 1 AND(((#PageIndex -1) * #PageSize + 1) + #PageSize) - 1
DROP TABLE #Results
END
Thanks for your help in advance.
If you want to get value of output parameter outside the method without changing the return type of the method, you may use out parameters in C#.
Change your method definition like below:
public DataSet GetOrderItemPictureByOrderId(int orderID, int PageIndex, out string outputValue)
{
//code here
outputValue = db.GetParameterValue(cmd, "#RecordCount");
//code here
}
and then call this method
string outvalue;
DataSet _ds = _orderPicDAC.GetOrderItemPictureByOrderId(OrderID, PageIndex,out outvalue;);
You will have the value in outvalue variable.
You can try with below
using (SqlConnection con = new SqlConnection(dc.Con))
{
using (SqlCommand cmd = new SqlCommand("SP_ADD", con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#OrderID", DbType.Int32, orderID);
con.Open();
cmd.ExecuteNonQuery();
}
}

How to get ID of the Last Inserted Record in SQL using ASP.net

Here is my code
protected void btnSubmit_Click(object sender, EventArgs e)
{
if (!string.IsNullOrWhiteSpace(Request.QueryString["id"]))
{
string clientId = Context.User.Identity.GetUserId();
if (clientId != null)
{
int id = Convert.ToInt32(Request.QueryString["id"]);
customize1 customize = new customize1
{
client_id = clientId,
product_id = id,
paper_type = Labelpt.Text,
corner = Labelpc.Text,
shipping_type = Labelsp.Text,
text = TextBox3.Text,
amount = Convert.ToInt32(lbResult.Text)
};
customizeModel model = new customizeModel();
Label9.Text = model.Insertcustomize(customize);
con.Open();
SqlCommand cmd2 = con.CreateCommand();
cmd2.CommandType = CommandType.Text;
cmd2.CommandText = "select top 1 * from customize1 where client_id='"+clientId+"' order by Id desc ";
cmd2.ExecuteNonQuery();
DataTable dt2 = new DataTable();
SqlDataAdapter da2 = new SqlDataAdapter(cmd2);
da2.Fill(dt2);
foreach (DataRow dr2 in dt2.Rows)
{
customizeid = dr2["Id"].ToString();
}
con.Close();
}
}
}
I need the last row id but my query does not generate any value.I also check my query in SSMS and query is working fine but in asp it is not generating any data and for inserting record i used the concept of class and entity relationship.
Any Solution.
Brother there are two ways:
One is when you insert your row place after the Insert query this:
SELECT SCOPE_IDENTITY()
For example:
INSERT INTO table_name (column1, column2, column3, ...)
VALUES (value1, value2, value3, ...);
SELECT SCOPE_IDENTITY()
It gives the inserted ID back.
The second way is this query;
SELECT id FROM table ORDER BY id DESC LIMIT 1
If you keep struggling with problems be open to ask more.

How can i retrive all grdiview columns values in one iteration without loop?

I'm facing problem in creating table programtically in asp.net c#. I'm working on sql project. I have a gridview and a button,When I click on button then I want that all gridview columns values e.g column_name,data type,allowNull,PrimaryKey etc.
All values inserted inside the "Create Table QUERY" in one iteration and table will be created, But I have a problem. I'm using for loop when loop first time execute then only one row iterate and table created in SQL only one column(Just first row) and when 2nd iteration execute then table name will be same ,so there is a issue.
Kindly tell me how can I resolve this issue.All values successfully inserted into the table but problem is in creating table. Table is created but 'ONLY LAST ' row table is created,Table contain only one row.How can i resolve this issue.
How can i do this?
Here is my "button" code aspx.cs`
public void insert(object sender, EventArgs e)
{
SqlConnection cnn = new SqlConnection("Data Source=HAMEED_KHAN\\SQLEXPRESS;Initial Catalog=db_compiler;Integrated Security=True");
string d=Session["value"].ToString();
SqlCommand cmd2=new SqlCommand("SELECT Database_id FROM Create_db WHERE Database_Name='"+d+"'",cnn);
cnn.Open();
string dbid = cmd2.ExecuteScalar().ToString();
cnn.Close();
int D_ID = Int32.Parse(dbid);
string str = "";
string type = "";
for (int i = 0; i < GridView2.Rows.Count; i++)
{
string tblname = "abc";
str=GridView2.Rows[i].Cells[1].Text.ToString();
type=GridView2.Rows[i].Cells[2].Text.ToString();
string Name = GridView2.Rows[i].Cells[1].Text.ToString();
string Type = GridView2.Rows[i].Cells[2].Text.ToString();
CheckBox allow=GridView2.Rows[i].Cells[3].Controls[0]as CheckBox;
CheckBox primary = GridView2.Rows[i].Cells[4].Controls[0] as CheckBox;
string s = Session["UID"].ToString();
int id = Int32.Parse(s);
string date = DateTime.Now.ToString();
string A = (allow.Checked == true ? "NULL" : "NOT NULL");
string P = (primary.Checked == true ? "PRIMARY KEY" : "");
// string query="USE "+d+" CREATE TABLE ABCD ("+Name+" "+Type+" "+A+")";
// SqlCommand cmd3 = new SqlCommand(query, cnn);
SqlCommand cmd = new SqlCommand("insertTbl", cnn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#Name", tblname);
cmd.Parameters.AddWithValue("#col_name", Name);
cmd.Parameters.AddWithValue("#dtype",Type);
cmd.Parameters.AddWithValue("#dbId", D_ID);
cmd.Parameters.AddWithValue("#allow",(allow.Checked==true ? "true" : "false"));
cmd.Parameters.AddWithValue("#primary", (primary.Checked == true ? "true" : "false"));
cmd.Parameters.AddWithValue("#user", id);
cmd.Parameters.AddWithValue("#date", date);
SqlDataAdapter ad = new SqlDataAdapter(cmd);
cnn.Open();
cmd.ExecuteNonQuery();
// cmd3.ExecuteNonQuery();
cnn.Close();
}
string str1=str;
string str2=type;
//string AA="ALLOW NULL";
// string queryy =string.Format(#"USE {"+d+"}; IF (NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dbo' AND TABLE NAME = 'ABCDE'))CREATE TABLE ABCDE ({"+str1+"} {"+type+"} {"+AA+"})");
string queryy="USE "+d+" If not exists (select name from sysobjects where name = 'Customers') CREATE TABLE Customers("+str1+" "+type+")";
SqlCommand cmd4 = new SqlCommand(queryy, cnn);
cnn.Open();
cmd4.ExecuteNonQuery();
cnn.Close();
}
You should make sure to avoid recreating the same table by using a rerunnable script. For CREATE TABLE, checking its existence is done this way:
string query = String.Format(#"
USE {0};
IF (NOT EXISTS (SELECT *
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'dbo'
AND TABLE_NAME = '{1}'))
CREATE TABLE {1} ({2} {3} {4})", d, "ABCD", Name, Type, A);
Notice that I have used String.Format to increase readability and avoid string concatenation (strings are immutable, so many instances are created when using + operator).
However, consider moving your CREATE TABLE outside of for loop, if your intention is to create once and insert multiple times. Anyway, existence check should be performed.
From C# 6.0, you can use both verbatim and interpolation (actually, string interpolation was introduced in 6.0). Something like this:
string query = $#"
USE {d};
IF (NOT EXISTS (SELECT *
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'dbo'
AND TABLE_NAME = 'ABCD'))
CREATE TABLE ABCD ({Name} {Type} {A})";

Filling a grid view with data of a table where one of the columns=one of the columns in a list

I have a list with two columns in it: ID; int, Score: Double.
In addition, I have a table in SQL SERVER with several columns.One of them is id:int.
I want to have a query like below:
select * from tbl where id = id s in my list.
My codes are below:
protected void btnfind_Click(object sender, EventArgs e)
{
List<KeyValuePair<int, double>> candidatelist = CalculateScores();
FinalMatch(candidatelist);
BindGrid(cmd2);//Contains codes for filling grid view with cmd2 , sql data reader
}
protected void FinalMatch(List<KeyValuePair<int, double>> finallist)
{
DataTable tvp = new DataTable();
tvp = ConvertToDatatable(finallist);
cmd2.CommandType = CommandType.StoredProcedure;
cmd2.CommandText = "dbo.DoSomethingWithCandidates";
SqlParameter tvparam = cmd2.Parameters.AddWithValue("#List", tvp);
tvparam.SqlDbType = SqlDbType.Structured;
cmd2.Connection = ClsDataBase.con;
}
protected DataTable ConvertToDatatable(List<KeyValuePair<int, double>> finallist)
{
DataTable dt = new DataTable();
dt.Columns.Add("ID");
dt.Columns.Add("Score");
foreach (var item in finallist)
{
var row = dt.NewRow();
row["ID"] = item.Key;
row["Score"] = item.Value;
dt.Rows.Add(row);
}
return dt;
}
protected void BindGrid(SqlCommand cmd)
{
if (ClsDataBase.con.State == ConnectionState.Closed)
ClsDataBase.con.Open();
SqlDataReader dr1 = cmd.ExecuteReader();
try
{
if (dr1.HasRows)
{
gv_allresults.DataSource = dr1;
gv_allresults.DataBind();
}
else
{
Response.Write("<script LANGUAGE='JavaScript' >alert('No Match')</script>");
}
if (dr1.IsClosed == false) dr1.Close();
}
catch (SqlException ex)
{
Response.Write("<script language='javascript'>alert(\"" + ex.ToString() + "\")</script>");
}
catch (Exception ex)
{
Response.Write("<script language='javascript'>alert(\"" + ex.ToString() + "\")</script>");
}
finally
{
ClsDataBase.con.Close();
}
}
And my codes in SQL server are:
CREATE TYPE dbo.CandidateList
AS TABLE
(
ID INT,
Score FLOAT
);
GO
CREATE PROCEDURE dbo.DoSomethingWithCandidates
#List AS dbo.CandidateList READONLY
AS
BEGIN
SET NOCOUNT ON;
SELECT ID FROM #List;
END
GO
I don't get the result. My procedure's codes are not complete. I don`t know what to do. Please help me.
Thanks so much.
Edited codes according to given suggestion:
protected void FinalMatch(List<KeyValuePair<int, double>> finallist)
{
int[] canArr = finallist.Select(x => x.Key).ToArray();
string csv = string.Join(",", canArr);
cmd2.CommandType = CommandType.StoredProcedure;
cmd2.CommandText = "dbo.ReturnCandidates";
cmd2.Parameters.AddWithValue("#LIST", csv);
cmd2.Connection = ClsDataBase.con;
}
And new codes in Sql server are:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[CSVToTable] (#InStr VARCHAR(MAX))
RETURNS #TempTab TABLE
(id int not null)
AS
BEGIN
;-- Ensure input ends with comma
SET #InStr = REPLACE(#InStr + ',', ',,', ',')
DECLARE #SP INT
DECLARE #VALUE VARCHAR(1000)
WHILE PATINDEX('%,%', #INSTR ) <> 0
BEGIN
SELECT #SP = PATINDEX('%,%',#INSTR)
SELECT #VALUE = LEFT(#INSTR , #SP - 1)
SELECT #INSTR = STUFF(#INSTR, 1, #SP, '')
INSERT INTO #TempTab(id) VALUES (#VALUE)
END
RETURN
END
GO
CREATE PROCEDURE dbo.ReturnCandidates
(
#LIST VARCHAR(200)
)
AS
BEGIN
SELECT *
FROM tblspecifications
WHERE id IN ( SELECT * FROM dbo.CSVToTable(#LIST) )
END
I get this error: "Procedure or function ReturnCandidates has too many arguments specified",
In below line:
SqlDataReader dr1 = cmd.ExecuteReader();
Please help me. Thanks a lot
I see cmd2.ExecuteNonQuery() missing.
Also, why not make a comma separated list of ID's and then send it to the SQL function. Example
int[] canArr= candidatelist.Select(x => x.Key).ToArray();
string csv = string.Join(",", canArr);
EDIT:
I created a SQL Fiddle for your query. It works.
http://sqlfiddle.com/#!6/c3d013/1/1

convert stamp to varchar and use it in c#

guys i created stored procedure to synchronize my data in a table from the main database to the branches using C# service using a last stamp. in the stored procedure i converted the stamp of the main database to varchar select #CurrentStamp = convert(varchar, value) from parameter where id = 3 this stamp i should get it in the C# as an output and send it as parameter to the stored procedure in the branch save the data that should i synchronize then save this stamp in a parameter table as varchar. all by testing without using the soap service. when i tried to use it in the soap service it throws an exception hexadecimal value 0x00, is an invalid character . any help please i tried to convert it to varbinary but it keep changing the stamp to another value. if any one knows how to let the XML read this values without exception please help.
FamilyService.FamilyService fs = new FamilyService.FamilyService();
DataSet ds = fs.GetFamilyToSynchronize(Current.LoggedUserSchool.ID, stamp, out currentStamp);
-
public static DataSet GetFamilyToSynchronize(int schoolID, string stamp, out string CurrentStamp)
{
DataTable dtFamilyToSynchronize = new DataTable();
DataTable dtFamilyPhones = new DataTable();
CurrentStamp = "";
DataSet ds = new DataSet();
try
{
using (DataBaseClass db = new DataBaseClass())
{
db.Connect();
SqlCommand command = db.CreateCommand();
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "GetFamilyToSynchronize";
command.Parameters.AddWithValue("#SchoolID", schoolID);
command.Parameters.AddWithValue("#Stamp", stamp);
command.Parameters.AddWithValue("#CurrentStamp", CurrentStamp);
command.Parameters["#CurrentStamp"].Direction = ParameterDirection.InputOutput;
command.Parameters["#CurrentStamp"].Size = 255;
SqlDataAdapter da = new SqlDataAdapter(command);
da.Fill(ds);
CurrentStamp = command.Parameters["#CurrentStamp"].Value.ToString();
}
}
catch (Exception ex){Logger.LogException(ex);}
return ds;
}
SQL Stored Procedure
GO
ALTER Proc [dbo].[GetFamilyToSynchronize] (#SchoolID int , #Stamp varchar(255) = null, #CurrentStamp varchar(255) output) as
select #CurrentStamp = convert(varchar, value) from parameter where id = 3
SELECT f.*
into #tmpFamily
FROM [Family] f
inner join fatherschools fs on fs.FamilyID = f.ID
where f.id =f.fatherlinkid --not in (select FatherLinkID from family )
and schoolID = #SchoolID
and (#Stamp is null or f.stamp> convert(timestamp, isnull(#Stamp,'')))
select distinct f.id, phonetypeid,phonenumber, t.FatherLinkID
from familyphones f
inner join #tmpFamily t on t.ID = f.FamilyID
select * from #tmpFamily

Categories