Long running SP never ends using sqlCommand - sql-server

I've got a quite expensive stored procedure in my SQL Server database. Launching it from the SQL Server Managment Studio requires some minutes. But I can't launch it via code using SqlCommand.
I've got this code:
spExecQuery = "EXEC [schema].[storedName]"
If I use this vb.NET snippet:
Using sqlCmd As SqlCommand = New SqlCommand(spExecQuery, conn)
sqlCmd.ExecuteNonQuery()
End Using
The script ends with "Timeout expired" error. But if I do:
Using sqlCmd As SqlCommand = New SqlCommand(spExecQuery, conn)
sqlCmd.CommandTimeout = 0
sqlCmd.ExecuteNonQuery()
End Using
The script never ends (it's running from at least 2 hours)... What am I missing? Thank you.

You need to specify first that it's a stored-procedure:
Using sqlCmd As SqlCommand = New SqlCommand(spExecQuery, conn)
sqlCmd.CommandType = CommandType.StoredProcedure
sqlCmd.CommandTimeout = 0
sqlCmd.ExecuteNonQuery()
End Using
You could also use QueueUserWorkItem to let the method run asynchronously, then you don't need to wait until it has finished:
Public Shared Sub ExecuteStoredProcedureAsync()
Threading.ThreadPool.QueueUserWorkItem(
New Threading.WaitCallback(AddressOf ExecuteStoredProcedure)
)
End Sub
Private Shared Sub ExecuteStoredProcedure(threadState As Object)
Dim sw = New Stopwatch()
sw.Start()
Try
' add code or call of long running method here '
Log.WriteInfo(String.Format("ExecuteStoredProcedure(async call) executed successfully, execution-time: {0}.", sw.Elapsed))
Catch ex As Exception
Log.WriteError(String.Format("Exception in ExecuteStoredProcedure (async call), execution-time: {0}.", sw.Elapsed))
End Try
End Sub

It should work if you specify the CmdType.
If still not working, try using the SqlDataReader
cmd.Connection = conn
cmd.CommandType = CommandType.StoredProcedure
cmd.CommandText = "proc_name"
Dim dr As SqlDataReader = cmd.ExecuteReader

try to add the command type to your sqlcommand
sqlCmd.CommandType = CommandType.StoredProcedure

Related

DBCC CheckDb - get sql messages in VB.NET

I am using this code to check my database for errors :
Dim cmd As New SqlCommand("DBCC CHECKDB (offpoDb) WITH TABLERESULTS", con)
cmd.ExecuteNonQuery()
But, u see, this command only generates SQL messages.
Is there any way to retrieve the messages in .net ?
Can i show the messages in a MessageBox ?
I've studied InfoMessage but i still fail to understand how to apply it/work with it.
Use a SqlDataReader instead of ExecuteNonQuery to get the recordset returned by TABLERESULTS:
Dim strBuilder As New System.Text.StringBuilder
Using cmd As New SqlClient.SqlCommand("DBCC CHECKDB (offpoDb) WITH TABLERESULTS", con)
Dim reader As SqlClient.SqlDataReader
reader = cmd.ExecuteReader
While reader.Read
strBuilder.AppendLine(CStr(reader("MessageText")))
End While
reader.Close()
End Using
MessageBox.Show(strBuilder.ToString)
To see all columns which are returned, execute the query in SQL Server Management Studio.
If you prefer to use the InfoMessage-event then add a handler and use it like following:
Sub MyMethod()
Using con As New SqlClient.SqlConnection("<yourConnectionString>")
con.Open()
AddHandler con.InfoMessage, AddressOf InfoMessage
Using cmd As New SqlClient.SqlCommand("DBCC CHECKDB (offpoDb)", con)
cmd.ExecuteNonQuery()
End Using
con.Close()
End Using
End Sub
Private Sub InfoMessage(sender As Object, e As SqlClient.SqlInfoMessageEventArgs)
MessageBox.Show(e.Message)
End Sub

When executing stored procedures in VB.NET/SQL, are we supposed to add "EXEC" or not?

I'm not sure what to believe anymore. When we are running our VB.NET SqlCommand off of stored procedures, do we add EXEC in our commands or not?!
I get an error:
Could not find stored procedure 'EXEC uspGrabAutoByYMM'.
But then other people tell me you MUST put EXEC in there for it to run.
Here's my sample code:
Public Sub BindGridAutosYMM()
Dim constring As String = "server=classified;database=classified"
Using con As New SqlConnection(constring)
Using cmd As New SqlCommand("EXEC uspGrabAutoByYMM", con)
cmd.Parameters.Add("#Year", SqlDbType.VarChar).Value = TextBox1.Text
cmd.Parameters.Add("#Make", SqlDbType.VarChar).Value = TextBox2.Text
cmd.Parameters.Add("#Model", SqlDbType.VarChar).Value = TextBox3.Text
cmd.CommandType = CommandType.StoredProcedure
Using sda As New SqlDataAdapter(cmd)
Using dt As New DataTable()
sda.Fill(dt)
DataGridView1.DataSource = dt
End Using
End Using
End Using
End Using
End Sub
No.
System.Data.CommandType.StoredProcedure does it for you.
It will be helpful: How to: Execute a Stored Procedure that Returns Rows
See too:
Using EXECUTE with Stored Procedures
You do not have to specify the EXECUTE keyword when you execute stored procedures when the statement is the first one in a batch.
EXECUTE (Transact-SQL)
If you remove the "exec" and the problem persists, confirm that this procedure exists in your database.

Using SqlBulkCopy with 2 Different Connection Strings

I have an application that gets information from one server (server config stuff) and puts it into a centralized database on another server. There are several servers that I loop over from a text file. I'm writing this application to eliminate the need for linked servers.
I'm trying to use SqlBulkCopy for copying the data but I'm running into problems. I have been successful using SqlBulkCopy with a single SQL connection but when I try to use 2 different SQL connections I run into problems. The data never reaches its destination database. I have debugged through the code and can see that it reaches the try/catch but it appears that the command bulkcopy.WriteToServer(reader) it doesn't actually write any data to SQL.
Dim connectionString As String = "Server= <ThatServer>; integrated security=true"
Dim connectionString2 As String = "Server= <MyServer>; Initial Catalog = <CentralizedDatabase>; integrated security=true"
Using sourceConnection As SqlConnection = _
New SqlConnection(connectionString)
sourceConnection.Open()
Dim commandSourceData As SqlCommand = New SqlCommand("<mySQLcommand>", sourceConnection)
Dim reader As SqlDataReader = commandSourceData.ExecuteReader
Using sourceConnection2 As SqlConnection = _
New SqlConnection(connectionString2)
sourceConnection2.Open()
Using destinationConnection As SqlConnection = _
New SqlConnection(connectionString2)
Using bulkcopy As SqlBulkCopy = _
New SqlBulkCopy(destinationConnection)
bulkcopy.DestinationTableName = _
"<MyTableName>"
Try
bulkcopy.WriteToServer(reader)
Catch ex As Exception
Console.WriteLine(ex.Message)
Finally
reader.Close()
End Try
End Using
End Using
sourceConnection2.Close()
End Using
sourceConnection.Close()
End Using
Can anyone see what I'm doing wrong? Thanks in advance!
**Solved. Here's my code that works:
Dim connectionString As String = "Server = <ThatServer>; Initial Catalog = <sourceDB>; integrated security = true"
Dim connectionString2 As String = "Server= <MyServer>; Initial Catalog = <destinationDB>; integrated security=true"
Using sourceConnection As SqlConnection = _
New SqlConnection(connectionString)
Dim commandSourceData As SqlCommand = New SqlCommand(<TSQL>, sourceConnection)
sourceConnection.Open()
Dim reader As SqlDataReader = commandSourceData.ExecuteReader()
Using destinationConnection As SqlConnection = _
New SqlConnection(connectionString2)
destinationConnection.Open()
Using bulkCopy As SqlBulkCopy = _
New SqlBulkCopy(destinationConnection)
bulkCopy.ColumnMappings.Add("SourceColumn1", "DestinationColumn1")
bulkCopy.ColumnMappings.Add("SourceColumn2", "DestinationColumn2")
bulkCopy.ColumnMappings.Add("SourceColumn3", "DestinationColumn3")
bulkCopy.ColumnMappings.Add("SourceColumn4", "DestinationColumn4")
bulkCopy.ColumnMappings.Add("SourceColumn5", "DestinationColumn5")
bulkCopy.ColumnMappings.Add("SourceColumn6", "DestinationColumn6")
bulkCopy.ColumnMappings.Add("SourceColumn7", "DestinationColumn7")
bulkCopy.DestinationTableName = "<destinationTable>"
bulkCopy.WriteToServer(reader)
End Using
destinationConnection.Close()
End Using
reader.Close()
sourceConnection.Close()
End Using

Close database connection on SQL Server using ADO .NET

I'm connecting to database using ADO .NET:
Dim conn As SqlConnection
Dim sqlcmd As SqlCommand
Dim da As SqlClient.SqlDataAdapter
Dim table As DataTable
conn = New SqlConnection(Utilities.ConnectionString)
sqlcmd = New SqlClient.SqlCommand()
sqlcmd.Connection = conn
sqlcmd.CommandType = CommandType.StoredProcedure
sqlcmd.CommandText = "mySP"
sqlcmd.Parameters.Add(New SqlClient.SqlParameter("#param", param1))
da = New SqlClient.SqlDataAdapter()
da.SelectCommand = sqlcmd
table = New DataTable()
da.Fill(table)
conn.Close()
sqlcmd.Connection.Close()
That works good.
When I launch on SQL Server the command:
EXEC SP_WHO2
For each call made from the previous code in ADO .NET, I have in the field Command the value: "AWAITING COMMAND", and in the field Status the value is "sleeping".
What does this means? The connection to database is still active? What should I do in order to close db connection?
The fact that after few hours you receive errors about connections exausted means that somewhere in your code you don't dispose correctly of your connection.
The code above seems correct, but what happen if you have exceptions? Are you sure to handle correctly the situation when your code exits unexpectedly from a method, due to exceptions?
The correct approach to this situation is refactoring your code.
Introduce everywhere the Using pattern. So your code above become:
Dim conn As SqlConnection
Dim sqlcmd As SqlCommand
Dim da As SqlClient.SqlDataAdapter
Dim table As DataTable
Using conn = New SqlConnection(Utilities.ConnectionString)
Using sqlcmd = New SqlClient.SqlCommand()
sqlcmd.Connection = conn
sqlcmd.CommandType = CommandType.StoredProcedure
sqlcmd.CommandText = "mySP"
sqlcmd.Parameters.Add(New SqlClient.SqlParameter("#param", param1))
da = New SqlClient.SqlDataAdapter()
da.SelectCommand = sqlcmd
table = New DataTable()
da.Fill(table)
End Using
End Using
This approach will ensure that your disposable objects (connection and command) will be released correctly and you will remove the subtle problem of connection leakings.

How to programmatically attach with server instance through vb.net

I need to attach my database, that resided in the MyData directory of my application folder, to the instance of SQL server on client's machine. How to do it?
Could any body give me vb.net code for that so my application does it when run for the first time?
Someone suggested me
Dim cmd As New SqlCommand()
' Dim vrMyConString As String=
Dim conn As System.Data.SqlClient.SqlConnection ' = New SqlConnection(vrMyConString)
cmd.CommandText = "sp_attach_db 'e:\dbTest.mdf', 'e:\dbTest.ldf'"
'conn.connectionstring =
conn.open()
cmd.CommandType = CommandType.StoredProcedure
cmd.Connection = conn
cmd.executenonquery()
but on conn.open, it returns error, Object reference not set to an instance of object
Thanks
This works on my Vb.net application.
Make sure sure your connection string: vrMyConString is correct and pointing to your database and with the correct details and it should work
Dim conn As SqlConnection = Nothing
conn = New SqlConnection(vrMyConString )
conn.Open()
You may use ADO.NET provider Linq to SQL or Entity Framework API.

Resources