Try to store the data into sqlserver - c#

i want to store the data in sqlserver and i'm able with this code.Now i want to check if table is exists than insert the data or create new table and insert the data..So i need help...thnku
SqlConnection con = new SqlConnection("Data Source=PRAWAT; Initial Catalog=StudentData ;Integrated security=true; ");
string query = "insert into NewValidStudentData(StudentId,Name,Marks) values (#StudentId,#Name,#Marks);";
SqlCommand cmd = new SqlCommand();
SqlDataAdapter da = new SqlDataAdapter();
da.InsertCommand = new SqlCommand(query, con);
con.Open();
da.InsertCommand.Parameters.Clear();
da.InsertCommand.Parameters.AddWithValue("#StudentId", System.Data.SqlDbType.NVarChar).Value = value[0];
da.InsertCommand.Parameters.AddWithValue("#Name", System.Data.SqlDbType.NVarChar).Value = value[1];
da.InsertCommand.Parameters.AddWithValue("#Marks", System.Data.SqlDbType.NVarChar).Value = value[2];
da.InsertCommand.ExecuteNonQuery();
con.Close();

You can edit your query to something like:
IF (EXISTS
(SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'YourSchemaName'// if you don't know the name, try 'dbo'
AND TABLE_NAME = 'NewValidStudentData'))
BEGIN
INSERT INTO NewValidStudentData(StudentId, Name, Marks)
VALUES (#StudentId, #Name, #Marks);";
END
Just wrap this query as a string and execute the same. This way, you can control the table's existence and insert the data within a single call to database server.

First check if your table exists with this snippet (also see this answer):
bool exists;
string tableName = "WhatEverItIs";
try {
// ANSI SQL way. Works in PostgreSQL, MSSQL, MySQL.
var cmd = new OdbcCommand(
"select case when exists((select * from information_schema.tables where table_name = '" + tableName + "')) then 1 else 0 end");
exists = (int)cmd.ExecuteScalar() == 1;
} catch {
try {
// Other RDBMS. Graceful degradation
exists = true;
var cmdOthers = new OdbcCommand("select 1 from " + tableName + " where 1 = 0");
cmdOthers.ExecuteNonQuery();
} catch {
exists = false;
}
}
Then if it wasn't exist:
if(!exists) {
var createTableSql = "CREATE TABLE WHAT_YOUR_TABLE_SCHEME_IS";
// execute a command with above createTableSql, to create your table
}
And then, do the rest of your code

StudentId as NVARCHAR? Does Student Id has characters in it?
IF NOT EXISTS (SELECT * FROM sys.objects
WHERE object_id = OBJECT_ID(N'[dbo].[NewValidStudentData]') AND type in (N'U'))
BEGIN
CREATE TABLE [dbo].[NewValidStudentData](
StudentId NVARCHAR(10),
Name NVARCHAR(100),
Marks NVARCHAR(3)
)
END
Note: I would suggest handle this in stored procedure instead of writing all this in c# code.

Related

How do I execute a SqlDataReader after sqlInsertCmd.ExecuteNonQuery

I am inserting a data row into my SQL Server database and then I want to query the data to get the unique identifier from the inserted row but my SqlDataReader is returning an empty dataset. I am thinking it maybe that the transaction hasn't been committed or something like that but I am not sure. I do not get an error.
Here is my code:
try
{
strQuery = "INSERT INTO clientnames VALUES(NEWID(),'" + txtACLastName.Text + "','" + txtACFirstName.Text + "'," + 1 + ")";
using (SqlCommand sqlInsertCmd = new SqlCommand(strQuery, sqlConn))
{
intQueryResult = sqlInsertCmd.ExecuteNonQuery();
if (intQueryResult == 0)
{
blnSuccess = false;
goto InsertClientNamesError;
}
else
{
blnSuccess = true;
}
sqlInsertCmd.Dispose();
}
if (blnSuccess)
{
strQuery = "select clientID from clientnames where firstname = '" + txtACFirstName.Text + "' and lastname = '" + txtACLastName.Text + "'";
using (SqlCommand sqlSelectCmd = new SqlCommand(strQuery, sqlConn))
{
SqlDataReader sqlDataRead = sqlSelectCmd.ExecuteReader();
while (sqlDataRead.Read())
{
strClientID = sqlDataRead.ToString();
}
sqlDataRead.Close();
sqlSelectCmd.Dispose();
}
}
}
catch (Exception exQuery)
{
System.Windows.MessageBox.Show("InsertClientNames: Error, " + exQuery.Message + ", has occurred.");
}
You are not getting the desired result because perhaps the SqlConnection is not opened explicitly (just a guess hard to tell without having full code). But this link shows you how to read from reader --> https://msdn.microsoft.com/en-us/library/haa3afyz(v=vs.110).aspx
But I suggest that you Please do not do it this way. Reason is you are making Two round trips to the DB Server when only one would have done the job for you IF you were using stored procedures. Also you are exposing yourselves to SQL Injection attacks as you are not parameterizing your queries.
Stored procedure:
CREATE PROCEDURE dbo.INS_clientnames
(
#FirstName varchar(100),
#LastName varchar(100),
#NewID int out
)
AS
BEGIN
Declare #Err int
set #NewID = NewID() -- Get the New ID and store it in the variable ( #NewID ) that the SP will return back to the caller
INSERT INTO clientnames values (#NewID , #FirstName , #LastName)
SET #Err = ##ERROR
IF #Error <> 0 -- Check If there was an error
Begin
SET #NewID = -1 -- Indicates that there was an error. You could log this into a Log Table with further details like error id and name.
END
RETURN
END
C# code to execute the above stored procedure and get the NewID:
using(SqlConnection conn = new SqlConnection(connectionString ))
{
using(SqlCommand cmd = new SqlCommand("dbo.INS_clientnames", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
// set up the parameters that the Stored Procedure expects
cmd.Parameters.Add("#FirstName", SqlDbType.VarChar, 100);
cmd.Parameters.Add("#LastName" , SqlDbType.VarChar, 100);
cmd.Parameters.Add("#NewId" , SqlDbType.Int).Direction = ParameterDirection.Output;
// set parameter values that your code will send to the SP as parameter values
cmd.Parameters["#FirstName"].Value = txtACFirstName.Text ;
cmd.Parameters["#LastName"].Value = txtACLastName.Text ;
// open connection and execute stored procedure
conn.Open();
cmd.ExecuteNonQuery();
// read output value from #NewId
int NewID = Convert.ToInt32(cmd.Parameters["#NewId"].Value);
}
}
Add the following line to your stored procedure that inserts the record
SELECT SCOPE_IDENTITY()
This will return the last identity value inserted in that table.
And use cmd.ExecuteScalar() instead of ExecuteNonQuery()
ExecuteScalar() executes the query, and returns the first column of the first row in the result set returned by the query. Additional columns or rows are ignored. [More info][1]
I see two approaches to do this:
either you generate the new GUID on the client side in your C# code and pass it into the query - then you already know what the new id is going to be, so you don't need to do a second query to get it:
you create your GUID on the server side and return it to the caller using the OUTPUT clause in your query
Approach #1:
// define connection string and query
string connStr = "--your connection string here--";
string query = "INSERT INTO dbo.Clients(ClientID, FirstName, LastName) VALUES(#ID, #First, #Last);";
using (SqlConnection conn = new SqlConnection(connStr))
using (SqlCommand cmd = new SqlCommand(query, conn))
{
// create the GUID in C# - this is the ID - no need to go get it again - this *IS* the id
Guid id = Guid.NewGuid();
// set the parameters
cmd.Parameters.Add("#ID", SqlDbType.UniqueIdentifier).Value = id;
cmd.Parameters.Add("#First", SqlDbType.VarChar, 50).Value = "Peter";
cmd.Parameters.Add("#Last", SqlDbType.VarChar, 50).Value = "Miller";
// open connection, execute query, close connection
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}
Approach #2:
// define connection string and query
string connStr = "--your connection string here--";
// query has an "OUTPUT" clause to return a newly inserted piece of data
// back to the caller, just as if a SELECT had been issued
string query = "INSERT INTO dbo.Clients(ClientID, FirstName, LastName) OUTPUT Inserted.ClientID VALUES(NEWID(), #First, #Last);";
using (SqlConnection conn = new SqlConnection(connStr))
using (SqlCommand cmd = new SqlCommand(query, conn))
{
// set the parameters - note: you do *NOT* send in a GUID value - the NEWID() will create one automatically, on the server
cmd.Parameters.Add("#First", SqlDbType.VarChar, 50).Value = "Frank";
cmd.Parameters.Add("#Last", SqlDbType.VarChar, 50).Value = "Brown";
// open connection
conn.Open();
// execute query and get back one row, one column - the value in the "OUTPUT" clause
object output = cmd.ExecuteScalar();
Guid newId;
if (Guid.TryParse(output.ToString(), out newId))
{
//
}
conn.Close();
}

How to get the schema name for sysobjects when querying a sql server database

I need to query a database for the name and schema name for all the stored procedures.
Here is what I've got so far but I do not know how to get the schema name.
What is the field name for the schema name when querying the sysobjects table?
private DataTable GetProcedures()
{
var table = new DataTable();
string sql = "";
sql = "select name,'' as type ";
sql += " From sysobjects ";
sql += " where type = 'P' ";
sql += " and name not like 'dt_%' ";
sql += " order by name asc";
using (SqlConnection conn = new SqlConnection(cs))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand())
{
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
cmd.CommandText = sql;
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
{
da.Fill(table);
}
}
}
return table;
}
Use the sys.objects table joined to the sys.schemas table like this:
SELECT schemas.name, objects.name
FROM sys.objects
JOIN sys.schemas ON schemas.schema_id = objects.schema_id
so to find all stored procedures (taking your query as a start), it looks like this:
SELECT schemas.name, objects.name
FROM sys.objects
JOIN sys.schemas ON schemas.schema_id = objects.schema_id
WHERE type = 'P'
AND objects.name NOT LIKE 'dt_%'
As additional information, you should no longer use sysobjects as it has been replaced with sys.objects, same goes for the other sys* tables.
Maybe this can help you :
SELECT name AS object_name
,SCHEMA_NAME(schema_id) AS schema_name
,type_desc
,create_date
,modify_date
FROM sys.objects
WHERE type = 'P'
ORDER BY name asc;

SQL Check if table Exists in C#, if not create

I think I've seen almost every page relating to this question, most likely answer was
Check if a SQL table exists
but didn't really understand it. This is what I got:
private void select_btn_Click(object sender, EventArgs e)
{
string theDate = dateTimePicker1.Value.ToString("dd-MM-yyyy");
SqlConnection SC = new SqlConnection("Data Source=ruudpc;Initial Catalog=leden;Integrated Security=True");
SqlCommand DateCheck = new SqlCommand("SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = '" + theDate + "'");
}
Now I want a return value from DateCheck.ExecuteScalar(); that can tell me if it exists or not, probably dead simple.
EDIT
Regardless for the sql injection part, and that for some this question is helpful, it is generally bad practice to create tables on the fly, I recommend you reconsider your ERD. Just saying.
Using IF EXISTS T-SQL
private void select_btn_Click(object sender, EventArgs e)
{
string theDate = dateTimePicker1.Value.ToString("dd-MM-yyyy");
// Enclose the connection inside a using statement to close and dispose
// when you don't need anymore the connection (to free local and server resources)
using(SqlConnection SC = new SqlConnection("Data Source=ruudpc;Initial Catalog=leden;Integrated Security=True"))
{
// Sql command with parameter
string cmdText = #"IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME=#name) SELECT 1 ELSE SELECT 0";
SC.Open();
SqlCommand DateCheck = new SqlCommand(cmdText, SC);
// Add the parameter value to the command parameters collection
DateCheck.Parameters.Add("#name", SqlDbType.NVarChar).Value = theDate
// IF EXISTS returns the SELECT 1 if the table exists or SELECT 0 if not
int x = Convert.ToInt32(DateCheck.ExecuteScalar());
if (x == 1)
MessageBox.Show("Table exists for date " + theDate);
else
MessageBox.Show("Table doesn't exist for date " + theDate);
}
}
The way you write the code can lead to sql injection attack.Parameterized SQL statements are an easy way to avoid SQL injection attacks and also a good codding practise
CREATE PROCEDURE checkTableExist
#theDate varchar(10)
AS
SET NOCOUNT ON;
IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME=#theDate) SELECT 1 ELSE SELECT 0
C# code
try
{
string theDate = dateTimePicker1.Value.ToString("dd-MM-yyyy");
sqlConnection = new SqlConnection(dbConnectionString);
SqlCommand command = new SqlCommand("checkTableExist", sqlConnection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("#theDate", SqlDbType.VarChar).Value = dateTimePicker1.Value.ToString("dd-MM-yyyy");
sqlConnection.Open();
int result = (Int32)command.ExecuteScalar();
sqlConnection.Close();
if (result == 1)
return true;//or any message
else
return false;
}
catch (SqlException ex)
{
Console.WriteLine("SQL Error" + ex.Message.ToString());
return false;
}

How to use insert and update command using c#

I have GridView and I am trying to check Task_ID from a table, if it is found then I want to update the record but if Task_ID is not found in the table then I want to insert it into my table. My code now does the insert part but it does not do the update part of the code. I was wondering how you can do this within the same code. Please help. thanks
here is my code:
int index = 0;
foreach (GridViewRow row in myGV.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
Label ID = row.FindControl("lbl_ID") as Label;
string UID = Request.Form[row.FindControl("hfUId").UniqueID];
DateTime strDate = DateTime.Now;
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["myCon"].ConnectionString);
SqlCommand cmd = new SqlCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "insert into myTable(TID, USR_ID, UPDT_DT) values(#ID, #USR_ID, #UPDT_DT) ";
cmd.Parameters.Add("#ID", SqlDbType.VarChar).Value = ID.Text;
cmd.Parameters.Add("#USR_ID", SqlDbType.VarChar).Value = UID.ToString();
cmd.Parameters.Add("#UPDT_DT", SqlDbType.VarChar).Value = strDate.Date;
cmd.Connection = con;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
con.Dispose();
cmd.Dispose();
}
index++;
}
There is a MERGE command in SQL for this purpose. Here is an example that might work for you:
Merge myTable As T
Using (Select Task_ID From myTable) As Src (Src_ID)
ON (T.Task_ID = Src.Src_ID)
WHEN MATCHED THEN
UPDATE SET T.UPDT_DT = 'your new value'
WHEN NOT MATCHED THEN
INSERT (TASK_ID, USR_ID, UPDT_DT)
VALUES (#TASK_ID, #USR_ID, #UPDT_DT);
change 'your new value' to the correct update statement
Replace the command text as below:
if not exists (select task_id from mytable where task_id = #task_id)
insert into myTable(TASK_ID, USR_ID, UPDT_DT) values(#TASK_ID, #USR_ID, #UPDT_DT)
else
update mytable set USR_ID = #USR_ID, UPDT_DT = #UPDT_DT where task_id = #TASK_ID
I would first query the database to see if the task_id existed... declare cmd, define it with a sql command like "Select count(*) from myTable where Task_ID = '" & Task_ID.text & "'" and assign that to some variable x. Then follow that with "if x <> 0 then --> define your cmd as an insert statement here, ELSE --> define cmd as "Update myTable set blah blah = values WHERE task_ID = " & task_ID.text.

using SQL to check if a table exists and if does then insert data from a different table?

ALTER PROC spTransferDat
#TableName nvarchar(50)
AS
EXEC('SELECT * FROM ClientGroups INTO [' + #TableName + '] ');
public void SPROC_ExecutionsTransferData()
{
string tablename = cboNetChannel.SelectedItem.ToString();
SqlConnection sqlConnectionCmdString = new SqlConnection(#"Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Users\Rick\Documents\Visual Studio 2010\Projects\Server\database\ClientRegit.mdf;Integrated Security=True;User Instance=True");
//Properly just transfer data to already existing table
string Command = "spTransferDat" + "'" + tablename + "'";
SqlCommand sqlCommand = new SqlCommand(Command, sqlConnectionCmdString);
sqlConnectionCmdString.Open();
sqlCommand.ExecuteNonQuery();
sqlConnectionCmdString.Close();
}
public void SPROC_ExecutionsTableNaming()
{
try
{
string tablename = cboNetChannel.SelectedItem.ToString();
SqlConnection sqlConnectionCmdString = new SqlConnection(#"Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Users\Rick\Documents\Visual Studio 2010\Projects\Server\database\ClientRegit.mdf;Integrated Security=True;User Instance=True");
//Properly Defines the string for naming the table according to the systems naming scheme
string renameCommand = "EXEC sp_rename 'NetworkAccount', " + "'" + tablename + "'";
SqlCommand sqlRenameCommand = new SqlCommand(renameCommand, sqlConnectionCmdString);
sqlConnectionCmdString.Open();
sqlRenameCommand.ExecuteNonQuery();
sqlConnectionCmdString.Close();
}
catch(Exception myex)
{
DialogResult QAnswer = MessageBox.Show("Table already exist, Do you want to just add data to table", "Data Management", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
//Check for command
if (QAnswer == DialogResult.Yes)
{
//transfer the data to the correct table if table already Exist
SPROC_ExecutionsTransferData();
}
else if (QAnswer == DialogResult.No)
{
this.Close();
}
}
}
All the SQL statements come back as an error, SQL does not allow duplicate tables naturally so I am trying to call this SQL procedure on the try error handling to add data to a table that already exists if a table is not created.
So what happens is I am copying a table then renaming the table with the sp_rename and if the table does not exist this works but if it exist it will error, so on the error I want to just insert all the data from one table to another but for some reason its not working the SQL procedure keeps saying the INTO statement is a statement error. NEED HELP!! thanks
I think this is correct code:
ALTER PROC spTransferDat
#TableName nvarchar(50)
AS
if OBJECT_ID(#TableName) is null
EXEC('SELECT * INTO [' + #TableName + '] FROM ClientGroups');
else
EXEC('insert INTO [' + #TableName + '] select * FROM ClientGroups');
if exists (select 1 from information_schema.tables where table_name = 'someTable')
-- do something
else
-- do something else
I'm fairly certain that the syntax you're looking for is more like this:
SELECT * INTO table FROM othertable

Categories