Stored procedure in loop - sql-server-2005

for (int i = 0; i < purchaseListView.Items.Count; i++)
Connection con = new Connection();
SqlCommand cmd = new SqlCommand();
SqlCommand cmdFifo = new SqlCommand();
con.OpenConnection();
cmd.Connection = con.DataBaseConnection;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "insertDetail";
cmdFifo.Connection = con.DataBaseConnection;
cmdFifo.CommandType = CommandType.StoredProcedure;
cmdFifo.CommandText = "insertInToMain";
This is my code and I want to know if the loop affects performance of my software and if this is the right way to call stored procedure in loop.
I have stored the procedure in a class and I want to call it from a form when the save button is clicked and insert 10 items in the database via same stored procedure.

Well, you are opening 10 connections, and it seems that you are not closing them, so you may run out of connections, but im guessing that's not the whole code, could you post the entire for ?

I would suggest you to create a table and insert the whole data into it by iterating through all the inputs ie., try to create a single stored procedure.
Running a for loop multpile times is inefficient and also the database will generate the result set number of times which will affect your performance as well due to network overhead.

You are creating a new connection object for every item which is highly inefficient.
Create one connection object and execute the stored procedure n times with the product details. Alternatively create a stored procedure to accept 10 items and insert the data at that level.
Move this outside the loop (You can access con and cmd inside the loop without creating a new instance:
Connection con = new Connection();
SqlCommand cmd = new SqlCommand();
con.OpenConnection();
cmd.Connection = con.DataBaseConnection;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "insertDetail";
Inside your loop, you can add all the parameters to the cmd object.
cmd.Parameters.Add("#Item", SqlDbType.Int);
cmd.Parameters["#Item"].Value = purchaseListView.Items[i];
cmd.ExecuteNonQuery();

You should set up your connection and stored procedure before the loop and only update command parameter values and exec within the loop. Like this:
Connection con = new Connection();
SqlCommand cmd = new SqlCommand();
SqlCommand cmdFifo = new SqlCommand();
con.OpenConnection();
cmd.Connection = con.DataBaseConnection;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "insertDetail";
cmd.Parameters.Add("#Item", SqlDbType.Int);
cmdFifo.Connection = con.DataBaseConnection;
cmdFifo.CommandType = CommandType.StoredProcedure;
cmdFifo.CommandText = "insertInToMain";
//now that your connections & commands are set up, you can reuse them within the loop
for (int i = 0; i < purchaseListView.Items.Count; i++)
{
//ToDo:assign any SP parameter values
cmd.Parameters["#Item"].Value = purchaseListView.Items[i];
// ...
//then exec within the loop
cmd.ExecuteNonQuery();
cmdFifo.ExecuteNonQuery();
}

Related

VB.NET - Stored procedure runs but parameters aren't working

I have the following bit of code:
Dim SQLCon As New SqlConnection
Dim cmd As New SqlCommand
Dim ds As New DataSet
SQLCon.ConnectionString = ConfigurationSettings.AppSettings("myConnString")
SQLCon.Open()
cmd.CommandType = CommandType.StoredProcedure
'run the stored procedure based on the view selected
If rdolstView.Items(0).Selected Then
cmd = New SqlCommand("spCondensedView", SQLCon)
ElseIf rdolstView.Items(1).Selected Then
cmd = New SqlCommand("spExtendedView", SQLCon)
End If
'filter by what the user searched for
If ddlSearchBy.SelectedValue = "Member" Then
cmd.Parameters.AddWithValue("#MbrNum", txtSearchFor.Text)
ElseIf ddlSearchBy.SelectedValue = "Assistant" Then
cmd.Parameters.AddWithValue("#AssignedAsst", ddlUWAssistants.SelectedValue)
ElseIf ddlSearchBy.SelectedValue = "Rep" Then
cmd.Parameters.AddWithValue("#Rep", txtSearchFor.Text)
ElseIf ddlSearchBy.SelectedValue = "Dept Assistant" Then
cmd.Parameters.AddWithValue("#DeptAsst", txtSearchFor.Text)
ElseIf ddlSearchBy.SelectedValue = "Creator" Then
cmd.Parameters.AddWithValue("#Creator", txtSearchFor.Text)
End If
Dim da As New SqlDataAdapter(cmd)
da.Fill(ds)
SQLCon.Close()
My problem is that the parameters don't seem to be working. Both stored procedures are supposed to take the optional parameter (either #MbrNum, #AssignedAsst, #Rep, #DeptAsst, or #Creator) and filter by it in its WHERE clause.
I've confirmed that this is working properly when I run the stored procedures manually in SQL Server Management Studio. I've also confirmed that the If/ElseIf statements are validating as true properly. So my code is definitely hitting the AddWithValue() statements when it's supposed to.
My returned result, however, is the full dataset without the filters applied, as if I ran the stored procedure with no parameters specified.
Any help would be awesome. Thanks!
Try specifying the a Command.Type...Set this when you create the command object.
cmd.CommandType = CommandType.StoredProcedure
By default it's set as Text I believe... Also wrap your connection and command's in Using statements so they are properly handled when done...

Wait until SQL Server Agent Job finishes

I am running a query to execute/start a SQL Server Agent Job which takes sometimes 4 to 5 hours to finish. I would like to wait until that job finishes and then continue with the program/code.
Here is my query I am running to start the stored procedure:
Dim connectionString As String = "HIDDEN"
Dim con As SqlConnection = New SqlConnection(connectionString)
con.Open()
Dim cmd As SqlCommand = New SqlCommand()
cmd.Connection = con
cmd.CommandText = "USE msdb; EXEC dbo.sp_start_job N'FWP FULL Daily'"
cmd.CommandType = CommandType.Text
cmd.ExecuteNonQuery()
con.Close()
// -- WAIT UNTIL STORED PROCEDURE FINISHES --
//Continue Code From Here on..........
How would I do this??
Thank you.

How efficient is it to reuse the command and connection object in ADO.net?

There is a specific requirement where in I am required to connect to two different Oracle databases one after the other. Does it make sense to create new connection and command objects or should I reuse them like below? (Not sure if this would even work-just some pseudo code here)
OracleConnection conn = new OracleConnection(ConnectionString1);
OracleCommand cmd = new OracleCommand("StoredProcedure1 , conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.parameters.add("param1", OracleDbType.Varchar2 , 20 , ParameterDirection.Input);
conn.open();
cmd.ExecuteNonQuery();
conn.close();
// Second DB hit
conn.ConnectionString = ConnectionString2;
cmd.CommandText = "StoredProcedure1";
if (cmd.Parameters.Count > 0) cmd.Parameters.Clear();
cmd.parameters.add("param2", OracleDbType.Varchar2 , 30 , ParameterDirection.Input);
conn.open();
cmd.ExecuteNonQuery();
conn.close();
All criticism welcome.

SQL UPDATE stored procedure from Visual studio

I have an UPDATE stored procedure that works good from SQL Server query:
GO
ALTER PROCEDURE [dbo].[UpdateMedicalCard]
#RecordingCode int,
#BeginTreatmentDate date,
#EndTreatmentDate date,
#MainDiagnosis nchar(100),
#AttendantDiagnosis nchar(100),
#TreatmentResult nchar(50)
AS
BEGIN
UPDATE MedicalCard
SET BeginTreatmentDate = #BeginTreatmentDate,
EndTreatmentDate = #EndTreatmentDate,
MainDiagnosis = #MainDiagnosis,
AttendantDiagnosis = #AttendantDiagnosis,
TreatmentResult = #TreatmentResult
WHERE RecordingCode = #RecordingCode
END
But when i call this procedure from Visual studio it does not update.
SqlConnection connection = new SqlConnection();
connection.ConnectionString = #"Data Source=.;Initial Catalog=Policlinic;Integrated Security=SSPI";
connection.Open();
SqlCommand myCommand = connection.CreateCommand();
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.CommandText = "UpdateMedicalCard";
myCommand.Parameters.Add("#RecordingCode", System.Data.SqlDbType.Int);
myCommand.Parameters["#RecordingCode"].Value = dataGridView1.CurrentRow.Cells[0].Value;
myCommand.Parameters.Add("#BeginTreatmentDate", System.Data.SqlDbType.Date);
myCommand.Parameters["#BeginTreatmentDate"].Value = dataGridView1.CurrentRow.Cells[3].Value;
myCommand.Parameters.Add("#EndTreatmentDate", System.Data.SqlDbType.Date);
myCommand.Parameters["#EndTreatmentDate"].Value = dataGridView1.CurrentRow.Cells[4].Value;
myCommand.Parameters.Add("#MainDiagnosis", System.Data.SqlDbType.NChar);
myCommand.Parameters["#MainDiagnosis"].Value = "qwe";
myCommand.Parameters.Add("#AttendantDiagnosis", System.Data.SqlDbType.NChar);
myCommand.Parameters["#AttendantDiagnosis"].Value = dataGridView1.CurrentRow.Cells[6].Value;
myCommand.Parameters.Add("#TreatmentResult", System.Data.SqlDbType.NChar);
myCommand.Parameters["#TreatmentResult"].Value = dataGridView1.CurrentRow.Cells[7].Value;
var dataAdapter = new SqlDataAdapter(myCommand);
var dataTable = new DataTable();
dataAdapter.Update(dataTable);
connection.Close();
I think i do smth wrong at the last 4 rows. Help please.
Your command isn't going to return any result rows, so you don't need to use a DataTable or DataAdapter. You just need to call connection.ExecuteNonQuery() instead.
You may also want to double check that the data (specifically the dates, as they can be tricky since the field may or may not also store a time component depending on how the table is defined, match an existing row.

How do you insert 9 MB file into a Blob Field Using Oracle.DataAccess?

Trying to insert a large audio file into an Oracle 10g database and keep getting this error:
ORA-01460: unimplemented or unreasonable conversion requested
The byte array length of the audio file is 2702577. The procedure works with smaller array lengths, but not the larger ones.
Here is my code and Thanks!
Dim oracleConnection As New OracleClient.OracleConnection
Dim Cmd As New OracleClient.OracleCommand
Dim oracleDataAdapter As New OracleDataAdapter
oracleConnection.ConnectionString = System.Configuration.ConfigurationManager.AppSettings("MasterConnectionODT")
Cmd.Connection = oracleConnection
Cmd.CommandText = "Audio.ADD_AUDIO"
Cmd.CommandType = CommandType.StoredProcedure
Dim aParam As New OracleClient.OracleParameter
aParam.ParameterName = "I_FACILITY_ID_C"
aParam.OracleType = OracleType.Char
aParam.Value = FacID
aParam.Direction = ParameterDirection.Input
Cmd.Parameters.Add(aParam)
aParam = New OracleParameter
aParam.ParameterName = "I_TARP_ID_N"
aParam.OracleType = OracleType.Number
aParam.Value = TarpID
aParam.Direction = ParameterDirection.Input
Cmd.Parameters.Add(aParam)
aParam = New OracleParameter
aParam.ParameterName = "I_AUDIO_BLOB"
aParam.OracleType = OracleType.Blob
aParam.Value = Audio
aParam.Direction = ParameterDirection.Input
Cmd.Parameters.Add(aParam)
Using oracleConnection
oracleConnection.Open()
Cmd.ExecuteNonQuery()
End Using
You can't pass parameters larger than 32k into a stored procedure. Change your command to SQL instead. So it would be something like:
Cmd.CommandText = "insert into yourtable values (:I_FACILITY_ID_C, :I_TARP_ID_N, :I_AUDIO_BLOB)"
Cmd.CommandType = CommandType.Text
If you still have trouble, you try using ODP.Net if you aren't already.