Is there any API available similar to JDBC batch update [PreparedStatement.addBatch() and PreparedStatement.executeBatch() ]?
I have seen the DataAdapter. However I think it is using DataTable; is it similar to JDBC PreparedStatement?
PreparedStatements in JDBC are directly analogous to SqlCommand, right down to supplying the statement and parameters. Here's an example:
var cmd = "UPDATE SomeTable SET Value = #Param1 WHERE ID = #ID";
using (var connection = new SqlConnection("Connection String Here"))
using (var command = new SqlCommand(cmd, connection))
{
command.Parameters.AddWithValue("#Param1", "NewValue");
command.Parameters.AddWithValue("#ID", 1);
connection.Open();
command.ExecuteNonQuery();
}
From what I've read, all the above should see very familiar for someone who uses PreparedStatement.
Related
I have a task to develop a console application that is a recon of values from a few tables in the DB. I have all the queries that I need for each value that is required and understand the logic on how the values will interact. The challenge I have is the best method to retrieve and store these values.
I have researched and successfully been able to create the static method to retrieve a single value from a single SQL query but I'm curious about the best method:
Create multiple methods to retrieve each value (upwards of 15 different select statements) summarised below (not complete code)
static double total1(int arg)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand command1 = new SqlCommand(commandText1, connection));
return(response);
}
}
static double total2(int arg)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand command2 = new SqlCommand(commandText2, connection));
return(response);
}
}
Try to combine all select statements in a single method (I've been unsuccessful here) summarised below (not complete code)
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (SqlCommand command1 = new SqlCommand(commandText1, connection))
{
}
using (SqlCommand command2 = new SqlCommand(commandText2, connection))
{
}
// etc
}
Create stored procedures in SQL and execute them and pass the parameters via the c# console app
I think method 1 is going to be taxing on the server as it would require the connection to open and close multiple times (although I don't know if that's as big a issue as I think it is). Method 2 seems more reasonable although I've followed the concepts here and I get stuck when trying to get the output of the commands (I'm using return). Method 3 seems smarter to me although I'd still be in a position where I need to choose between methods 1 & 2 to execute the SP's.
I would really appreciate advice and guidance here, I'm new to C# so this is a steep learning curve when tutorials don't cover the sort of thing (or at least I can't define my problem properly)
string query = "SELECT * FROM table1;";
query += "SELECT * FROM table2";
using (SqlConnection con = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand(query))
{
using (SqlDataAdapter sda = new SqlDataAdapter())
{
cmd.Connection = con;
sda.SelectCommand = cmd;
using (DataSet ds = new DataSet())
{
sda.Fill(ds);
}
}
}
}
I've recently seen that this question is still being viewed so I'll post the solution for anyone who is just starting off developing and encounters a similar challenge.
The most suitable solution was to create a stored procedure, pass each unique argument to it and return all the relevant data in a single response to the application. A custom model was defined for this output and the application logic adapted accordingly. The result is a longer running single call to the database as opposed to multiple individual ones.
Using the format from the question, the solution was:
C# code
static NewModel AllTotals(int arg1, int arg2)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
var commandText = "TheStoredProcName";
SqlCommand command = new SqlCommand(commandText, connection));
command.CommandType = System.Data.CommandType.StoredProcedure;
Cmd.Parameters.AddWithValue("#arg1", arg1);
Cmd.Parameters.AddWithValue("#arg1", arg2);
using (SqlDataReader dr = Cmd.ExecuteReader())
{
while (dr.Read())
{
var response = new NewModel(){
Value1 = Convert.ToDecimal(dr["value1"]),
Value2 = Convert.ToDecimal(dr["value2"]),
};
return(response);
}
}
}
return null;
}
SQL Stored Proc
CREATE PROCEDURE [dbo].[TheStoredProcName]
#arg1 int,
#arg2 int
AS
DECLARE #value1 decimal(18,6) = ISNULL((--QUERY TO GET VALUE1),0)
DECLARE #value2 decimal(18,6) = ISNULL((--QUERY TO GET VALUE2),0)
-- select the variables into a result set for the application
SELECT #value1 as [value1], #value2 as [value2]
Trying to improve my C# to SQL skills... Currently I am using this bit of code to pull data from our application server. I have two different DBA's telling me two other ways to write this, just trying to figure out if this should be improved on or changed. If so, I would really appreciate some kind of examples.
FYI: This code...
db.con(user.Authority)
...Is essentially a 'new sqlconnection' code.
DataTable dtInfo = new DataTable("SomeInfo");
using (SqlConnection con = db.con(user.Authority))
{
string command = "SOME SQL STATEMENT;";
using (SqlCommand cmd = new SqlCommand(command,con))
{
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("#Param", sqlDbType).Value = Param;
con.Open();
cmd.ExecuteNonQuery();
**********
*** OR ***
**********
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("#Param", sqlDbType).Value = Param;
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
{
da.Fill(dtInfo );
}
}
}
So, if I'm understanding the provided information, this is my best route?
using (SqlConnection con = db.con(user.Authority))
{
string command = "SELECT [TBL_EMPLOYEE].[ACTIVE_DIRECTORY] FROM [TBL_EMPLOYEE];";
using (SqlCommand cmd = new SqlCommand(command, con))
{
con.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
MessageBox.Show(reader["ACTIVE_DIRECTORY"].ToString());
}
}
}
And one last thing... This should prevent the need for
cmd.Dispose();
etc...
The code would depend on the specific query. If the query retrieves rows of data (as a SELECT does), then you would go the da.Fill() route. If it's a query that just makes a change to the database (such as INSERT, UPDATE, or DELETE), then you would use ExecuteNonQuery().
I would not use the SqlDataAdapter version. The version that uses the SqlCommand object and the SqlDataReader will perform better, and allows more insight into the actual data being returned.
// Assumes the following sql:
// SELECT foo, bar FROM baz
// error checking left out for simplicity
var list = new List<SomeClass>();
using(var reader = cmd.ExecuteReader()) {
while(reader.Read()) {
list.Add(new SomeClass {
// NOTE: you can see the columns that the c# is referencing
// and compare them to the sql statement being executed
Foo = (string)reader["foo"],
Bar = (string)reader["bar"]
});
}
}
Later as your level of experiance increases you will be able to use other features of the SqlCommand and SqlDataReader classes in order to ensure that the code executes as quickly as possible. If you start using the SqlDataAdapter route, you will eventually have to relearn how to do the exact same things you have already been doing because the SqlCommand and SqlDataReader have operations that do not exist elsewhere in .NET.
ExecuteNonQuery returns the number of rows effected.
A DataTable is not an efficient way to retrieve that number.
int rowsRet = cmd.ExecuteNonQuery();
SqlCommand.ExecuteNonQuery Method
I am quit busy turning a old classic asp website to a .NET site. also i am now using SQL Server.
Now I have some old code
strsql = "select * FROM tabel WHERE ID = " & strID & " AND userid = " & struserid
rs1.open strsql, strCon, 2, 3
if rs1.eof THEN
rs1.addnew
end if
if straantal <> 0 THEN
rs1("userid") = struserid
rs1("verlangid") = strID
rs1("aantal") = straantal
end if
rs1.update
rs1.close
I want to use this in SQL Server. The update way. How can I do this?
How can I check if the datareader is EOF/EOL
How can I insert a row id it is EOF/EOL
How can I update a row or delete a row with one function?
If you want to use raw SQL commands you can try something like this
using (SqlConnection cnn = new SqlConnection(_connectionString))
using (SqlCommand cmd = new SqlCommand())
{
cnn.Open();
cmd.Connection = cnn;
// Example of reading with SqlDataReader
cmd.CommandText = "select sql query here";
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
myList.Add((int)reader[0]);
}
}
// Example of updating row
cmd.CommandText = "update sql query here";
cmd.ExecuteNonQuery();
}
It depends on the method you use... Are you going to use Entity Framework and LINQ? Are you going to use a straight SQL Connection? I would highly recommend going down the EF route but a simple straight SQL snippet would look something like:
using (var connection = new SqlConnection("Your connection string here"))
{
connection.Open();
using (var command = new SqlCommand("SELECT * FROM xyz ETC", connection))
{
// Process results
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
int userId = (int)reader["UserID"];
string somethingElse = (string)reader["AnotherField"];
// Etc, etc...
}
}
}
// To execute a query (INSERT, UPDATE, DELETE etc)
using (var commandExec = new SqlCommand("DELETE * FROM xyz ETC", connection))
{
commandExec.ExecuteNonQuery();
}
}
You will note the various elements wrapped in using, that is because you need to release the memory / connection when you have finished. This should answer your question quickly but as others have suggested (including me) I would investigate Entity Framework as it is much more powerful but has a learning curve attached to it!
You can use SQL store procedure for Update. And call this store procedure through C#.
Create procedure [dbo].[xyz_Update]
(
#para1
#para2
)
AS
BEGIN
Update tablename
Set Fieldname1=#para1,
Set Feildname2=#para2
end
Problem statement.
Basically I get 3 - 50 parameters that come back from a web service as a NVP array I then need to loop over them create the SQL command parameters for each and call the stored procedure. Is there a more efficient way to handle it than the approach below?
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (SqlCommand cm = connection.CreateCommand())
{
cm.CommandText = "MySproc";
cm.CommandType = CommandType.StoredProcedure;
foreach (var field in row)
{
cm.Parameters.AddWithValue("#" + field.Key.ToString(), field.Value.ToString());
}
cm.ExecuteNonQuery();
}
}
I personally use the ISNULL or COALESCE in the WHERE clause of the stored procedure. Unless your looking to do it inside your c#...
http://blogs.x2line.com/al/archive/2004/03/01/189.aspx
I'm trying to return the rowcount from a SQL Server table. Multiple sources on the 'net show the below as being a workable method, but it continues to return '0 rows'. When I use that query in management studio, it works fine and returns the rowcount correctly. I've tried it just with the simple table name as well as the fully qualified one that management studio tends to like.
using (SqlConnection cn = new SqlConnection())
{
cn.ConnectionString = sqlConnectionString;
cn.Open();
SqlCommand commandRowCount = new SqlCommand("SELECT COUNT(*) FROM [LBSExplorer].[dbo].[myTable]", cn);
countStart = System.Convert.ToInt32(commandRowCount.ExecuteScalar());
Console.WriteLine("Starting row count: " + countStart.ToString());
}
Any suggestions on what could be causing it?
Here's how I'd write it:
using (SqlConnection cn = new SqlConnection(sqlConnectionString))
{
cn.Open();
using (SqlCommand commandRowCount
= new SqlCommand("SELECT COUNT(*) FROM [LBSExplorer].[dbo].[myTable]", cn))
{
commandRowCount.CommandType = CommandType.Text;
var countStart = (Int32)commandRowCount.ExecuteScalar();
Console.WriteLine("Starting row count: " + countStart.ToString());
}
}
Set your CommandType to Text
command.CommandType = CommandType.Text
More Details from Damien_The_Unbeliever comment, regarding whether or not .NET defaults SqlCommandTypes to type Text.
If you pull apart the getter for CommandType on SqlCommand, you'll find that there's weird special casing going on, whereby if the value is currently 0, it lies and says that it's Text/1 instead (similarly, from a component/design perspective, the default value is listed as 1). But the actual internal value is left as 0.
You can use this better query:
SELECT OBJECT_NAME(OBJECT_ID) TableName, st.row_count
FROM sys.dm_db_partition_stats st
WHERE index_id < 2 AND OBJECT_NAME(OBJECT_ID)=N'YOUR_TABLE_NAME'