Hi Dave,
Yikes!!!
The code you provided is just laced with performance killers. Dropping
and recreating stored procedures means updates to system tables.
Yes, you're correct. I lose a full second on this! Damn!
the SP is only ever being executed once. SPs are always compiled for
their first execution so on top of the hit from updating the system
tables, you're forcing a compile every time the SP executes.
That's because the sp is different every time. This too costs me, after
all, as you correctly point out, it's not compiled yet. This also can
cost
me anywhere from 2 - 10 seconds! Good God!
Dave, I hear this performance nonsense all the time. In the practical
world, a function like this runs in 15 seconds. Give me a break.
Bernie
Yikes!!!
The code you provided is just laced with performance killers. Dropping
and recreating stored procedures means updates to system tables.
Additionally, the SP is only ever being executed once. SPs are always
compiled for their first execution so on top of the hit from updating
the
system tables, you're forcing a compile every time the SP executes.
I would strongly suggest reading
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/tsqlref/ts_sp_ea-ez_2h7w.asp
for some information about using SPs that execute dynamic SQL. Also
note
that using the Prepare() method of the SqlCommand class has a similar
effect. Both of these methods avoid the constant updates to the system
tables and will improve the operation of your application.
On another, possibly moot point, this code doesn't apply to Tor's
question. This code is specific to SQL Server while he's asking about
the
classes contained in System.Data.OleDb (OleDbCommand, OleDbParameter,
etc...) and is referring to an Access database.
Hi Tor,
Actually, I've found that the best way to do this is indeed to pass an
array. Now I know you can't, but you can, in effect, if you create
the
sp 'on the fly'. What I do is I first delete the sp; then I create a
bulkstring to contain my array - '12345', '34225', '957433', etc.
Then I
construct the sp, create it from the vb code, and run it. Below is an
example of one such function I use.
HTH,
Bernie Yaeger
Public Function createa_rsummary(ByVal marraylist As ArrayList, ByVal
oconn As SqlConnection) As Integer
createa_rsummary = 0
Dim i As Integer
Dim bulkstring As String
Dim acount As Integer = 0
For i = 0 To marraylist.Count - 1
acount += 1
bulkstring += Chr(39) & Trim(marraylist(i)) & Chr(39) & ","
If i <> marraylist.Count - 1 Then ' ie, it isn't the last item
If acount > 20 Then
acount = 0
bulkstring += vbCrLf
End If
End If
Next
bulkstring = Mid(bulkstring, 1, bulkstring.Length - 1) & ")"
Dim dcmd As New SqlCommand
dcmd = New SqlCommand("sp_dropsp_createa_rsummary", oconn) ' drop the
sp
dcmd.CommandType = CommandType.StoredProcedure
Try
dcmd.ExecuteNonQuery()
Catch ex As Exception
MessageBox.Show(ex.message)
End Try
Dim creationstring As String
creationstring = "CREATE PROCEDURE sp_createa_rsummary AS " _
& "if exists (select * from information_schema.tables where table_name
=
" _
& "'a_rsumtable')" & vbCrLf & "drop table a_rsumtable" & vbCrLf _
& "select imcacct, pubcode, invnum, inv_dt, brname, " _
& "(case when inv_dt + 31 > getdate() then balance else 0 end) as
under31, " _
& "(case when inv_dt + 61 > getdate() and inv_dt + 31 <= getdate()
then
balance else 0 end) as over30, " _
& "(case when inv_dt + 91 > getdate() and inv_dt + 61 <= getdate()
then
balance else 0 end) as over60, " _
& "(case when inv_dt + 121 > getdate() and inv_dt + 91 <= getdate()
then
balance else 0 end) as over90, " _
& "(case when inv_dt + 121 <= getdate() then balance else 0 end) as
over120" _
& " into a_rsumtable from a_r where imcacct" _
& " in (" & bulkstring & vbCrLf _
& "order by pubcode, imcacct"
Dim sqladapt As New SqlDataAdapter
sqladapt.SelectCommand = New SqlCommand(creationstring, oconn)
Try
sqladapt.SelectCommand.ExecuteNonQuery() ' create the sp
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
Dim ocmd As New SqlCommand
ocmd = New SqlCommand("sp_createa_rsummary", oconn) ' execute the sp
ocmd.CommandType = CommandType.StoredProcedure
Try
ocmd.ExecuteNonQuery()
Catch ex As Exception
MessageBox.Show(ex.message)
End Try
Dim acmd As New SqlCommand
acmd = New SqlCommand("sp_altera_rsumtable", oconn) ' give new table a
pk
acmd.CommandType = CommandType.StoredProcedure
Try
acmd.ExecuteNonQuery()
Catch ex As Exception
MessageBox.Show(ex.message)
End Try
' we now have a_rsumtable for only the selected accounts
createa_rsummary = 1
End Function
"Tor Martin Halvorsen" <
[email protected]>
wrote in message
Hi all,
Just for fun, I was investigating wheither I could use
OleDbParameters
in
queries with WHERE IN() clauses.
Given the code:
...
cmd.CommandText = "SELECT title, txt FROM tblFoo WHERE bar IN(?)";
int ids[] = {1, ... };
for(int i=0; i<ids.Length; i++)
cmd.Parameters.Add().Value = ids[ i ];
...
After some hours with head scratching and banging I found that for
every
record I needed to get I had to add a new question-mark to the IN()
clause.
Now, this isn't a lot better than the good old string-concatenation i
usually use
since i have to figure out how many question-marks are needed in the
clause.
So is there a more elegant way to use OleDbParameters with IN
clauses?
Obviously passing an array to the parameter won't work, and a single
question-mark will only use the first parameter.