I created a CLR procedure to download email files. It works perfectly, the problem that when it is running it is not listed when I query the server processes.
Does anyone know a way to get it in sql server processes?
I'm using the query below
exec dbo.sp_download_files_mail
If you are expecting to see exec dbo.sp_download_files_mail in sys.dm_exec_sql_text via the sys.dm_exec_requests.plan_handle, then that's probably not going to happen. When you use EXEC it creates a sub-process that is probably a different execution plan. In the case of SQLCLR, SQL Server has no insight into what is happening unless you are executing T-SQL using SqlConnection, and then you will get the plan for the SQL being executed within the SQLCLR object and not the plan for the SQLCLR object itself. When you are executing a SQLCLR object and it is not executing any T-SQL statements, then both the sql_handle and plan_handle values are empty: 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.
However, you can see the SQLCLR object showing up in the plan_handle value coming back from sys.dm_exec_cached_plans. The SQLCLR object does seem to appear in this DMV upon being executed, but as this DMV reports cached objects, it does not necessarily get removed once the SQLCLR object completes. Hence, you can't use this DMV to indicate current running status of the object. Nor does the plan_handle value reported in sys.dm_exec_cached_plans show up in sys.dm_exec_requests while it is running.
You can test this behavior yourself by creating a SQLCLR Stored Procedure or SQLCLR scalar User-Defined Function that does nothing more than call System.Threading.Thread.Sleep() for at least 30 seconds. If you do not want to deal with creating this, a pre-made SQLCLR UDF – DB_WaitForDelay – exists in the Free version of the SQL# SQLCLR library (that I created) and is what I used in the example code below.
In SQL Server Management Studio (SSMS), open up two query tabs and paste in the following:
TAB 1
EXEC [SQL#].[DB_WaitForDelay] 30000, 1;
TAB 2
SELECT txt.*, req.*
FROM sys.dm_exec_requests req
OUTER APPLY sys.dm_exec_sql_text(req.[plan_handle]) txt
WHERE req.[session_id] = <session_id_of_Tab1>;
DBCC INPUTBUFFER(<session_id_of_Tab1>);
SELECT txt.*, cp.*
FROM sys.dm_exec_cached_plans cp
OUTER APPLY sys.dm_exec_sql_text(cp.[plan_handle]) txt
WHERE cp.[cacheobjtype] LIKE N'CLR%';
Once you have replaced the two instances of "<session_id_of_Tab1>" in the Tab 2 query, execute the Tab 1 query, then go back to Tab 2 and execute that batch of queries.
IF you really need to know if this SQLCLR object is executing as it is executing, then you will have to do something along the lines of using SqlConnection with a ConnectionString of Context Connection = true; and then execute (at the beginning of the SQLCLR object) something like SET CONTEXT_INFO 0x1234; (assuming that you are not already using CONTEXT_INFO for something else). At the end of the SQLCLR object, execute a 2nd SqlCommand for SET CONTEXT_INFO 0x00; to clear it out.
This approach allows you to use the following query to confirm that it is currently running:
SELECT req.*
FROM sys.dm_exec_requests req
WHERE req.[context_info] = 0x1234;
Also, it is a rather bad practice to prefix Stored Procedure names with sp_ as that causes SQL Server to first check in [master] for the object and then the current Database. Using something like spDownloadEmailFiles is better, though still no real good reason to prefix Stored Procedure / Function / Table / View names with anything.
Related
I'm trying to call a simple stored procedure which would return a list of names in normal test format, all in a single line. I'm passing it two parameters, but no matter how i setup the call, either within a OLE DB Source Editor, or within an execute SQL task.
There must be something i'm missing with my SQL statement b/c i keep getting an error.
My SQL command text is
EXEC [dbo].[spGetEmployerIdCSV] ?, ?
The parameters I'm passing are listed exactly as they are declared in the stored procedure, #IDType and #IDNumber, which are mapped to predefined variables.
Every time I try to run it from either task type, I get a
The EXEC SQL construct or statement is not supported.
What is the best way to run a stored procedure within SSIS?
Thank you.
I cannot recreate your issue.
I created a control flow with the proc already in existence.
I have my execute sql task configured as
My parameters tab shows
When I click run, the package goes green.
My initial assumption was that you had signaled that you were using a stored procedure and were erroneously providing the EXEC part. I had done something similar with SSRS but even updating the IsQueryStoredProcedure to True, via Expression, I could not regenerate your error message.
If you are doing something else/different/in addition to what I have shown in the Execute SQL Task, could you amend your question to describe what all functionality the procedure should show.
Did you specify output parameters?
For 2 in / 1 out your SQL code will look like:
EXEC [dbo].[spGetEmployerIdCSV] ?, ?, ? OUTPUT
ResultSet has to be set to none!
I had the same problem.
When you execute the task check the 'Progress' tab; this will give you a 'fully fledged' error details.
In my case I didn't map the parameter which I created in the SQL Task to the actual one in the Stored Procedure.
So, double click the SQL Task, click on Parameter Mapping on the left hand side, then Create the parameters and their respective mappings. Here is a screenshot (in version 2012):
I faced with a similar issue after upgrading to SSDT for VS 2013 (the problem was with lookup element).
Fixed by using this answer:
EXEC ('dbo.MyStoredProcedure')
WITH RESULT SETS
(
(
MyIntegerColumn INT NOT NULL,
MyTextColumn VARCHAR(50) NULL,
MyOtherColumn BIT NULL
)
)
use the same command you use to run the stored procedure in MySQL workbench
call ();
USE this command in Execute SQL Task
I want to execute a stored procedure virtually and get the returned columns. I use fmtonly like below :
set fmtonly on
exec spName null
set fmtonly off
but using fmtonly caused to run all the lines of code and result of this work is ERROR.
Is there any solution for doing this work?
You need to use sp_describe_first_result_set which is new to SQL Server 2012. Note that this requires you to provide the input parameters (at least the types).
In T-SQL development one is expected to know what procedures is calling and what is the expected result set. Before SQL server 2012 there was very little support for dynamic, runtime, discovery of procedure output and required parameters. This new procedure, along with others like sp_describe_undeclared_parameters can be used to create tools that need to explore the available programming API surface. The very fact that these were added to 2012 should indicate that the equivalent cannot be properly handled pre-2012. Solutions like loopback linked servers have many problems, primarily because they actually execute the code with potential disastrous effects.
I have a SQL Server 2000 database with a stored procedure that deletes a row from a specific table, given its id. When I call the stored procedure from VB.NET, it does not delete the row, but running the same script directly on the database via SSMS, it works.
Here's my chain of events:
Start SQL Server Profiler to watch all calls to the database. I have
it setup to track when stored procedure starts, completes, and even
on SQL statements start/complete within that stored procedure.
Call stored procedure via VB.NET dll.
Stop the profiler trace to avoid excessive data to dig through.
Select from table, and see that the row still exists.
View the profiler trace, which only shows RPC:Starting, SP:Starting, RPC:Completed. No inner statements are traced, which verifies why the row wasn't deleted since the delete statement never fired.
Copy/paste the EXEC call directly from the RPC:Starting trace entry from when it was called via VB.NET, into SQL Server Management Studio query window pointed to the same database with same credentials.
Start profiler again.
Execute EXEC statement from bullet 6 in SSMS.
Stop profiler.
Select from table, and see that the row GOT DELETED like it should.
View the profiler trace, which shows SP:Starting, all statements starting/completed including the DELETE statement, and SP:Completed.
Why would running it via RPC make it not execute any of the statements in the proc, but running directly acts as it should?
EDIT: Below is my VB.NET code. This is the same code we use in over 100 other places:
Dim paramRowID As New SqlParameter("#RowID", sRowID)
Microsoft.ApplicationBlocks.Data.SqlHelper.ExecuteNonQuery(oConn, "spDeleteRow", paramRowID)
See SqlHelper source here.
EDIT: I hate myself right now. :) SQL threw an exception "nvarchar is incompatible with image" about another parameter that I was passing NULL to. SSMS didn't worry about the type, but VB.NET did since I didn't explicitly tell it that it was of type image. Once I defined that param, it worked. I wish profiler would have told me there was an error though.
Any help would be appreciated,
Greg
That would be because SSMS does not call an RPC but a batch. There is no way in fact to call a RPC from SSMS since you cannot declare a parameter, which is what differentiate an RPC call from a batch call in TDS:
2.2.1.3 SQL Batch To send a SQL statement or a batch of SQL statements, the SQL batch, represented by a Unicode string, is copied into the data section of a TDS packet and then sent to the database server that supports SQL. A SQL batch may span more than one TDS packet. See section 2.2.6.6 for additional detail
2.2.1.5 Remote Procedure Call To execute a remote procedure call (RPC) on the server, the client sends an RPC message data stream to the server. This is a binary stream that contains the RPC name or numeric identifier, options, and parameters. RPCs MUST be in a separate TDS message and not intermixed with SQL statements. There can be several RPCs in one message. See section 2.2.6.5 for additional details.
So monitor instead for the SQL:BatchCompleted event and you'll see your SSMS statement(s).
Does the user the application is using to connect to sql have permission to execute stored procedures? That is the first thing I would verify.
I am trying to use an ODBCdataadapter in C# to run a query which needs to select some data into a temporary table as a preliminary step. However, this initial select statement is causing the query to terminate so that data gets put into the temp table but I can't run the second query to get it out. I have determined that the problem is the presence of two select statements in a single dataadapter query. That is to say the following code only runs the first select:
select 1
select whatever from wherever
When I run my query directly through SQL Server Management Studio it works fine. Has anyone encountered this sort of issue before? I have tried the exact same query previously on similar databases using the same C# code (only the connection string is different) and had no problems.
Before you ask, the temp table is helpful because otherwise I would be running a whole lot of inner select statements which would bog down the database.
Assuming you're executing a Command that's command type is CommandText you need a ; to separate the statements.
select 1;
select whatever from wherever;
You might also want to consider using a Stored Procedure if possible. You should also use the SQL client objects instead of the ODBC client. That way you can take advantage of additional methods that aren't available otherwise. You're supposed to get better perf as well.
If you need to support multiple Databases you can just use the DataAdapter class and use a Factory o create the concrete types. This gives you the benefits of using the native drivers without being tied to a specific backend. ORMS that support multiple back ends typically do this. The Enterprise Library Data Access Application Block while not an ORM does this as well.
Unfortunately I do not have write access to the DB as my organization has been contracted just to extract information to a data warehouse. The program is one generalized for use on multiple systems which is why we went with ODBC. I suppose it would not be terrible to rewrite it using SQL Management Objects.
ODBC Connection requires a single select statement and its retrieval from SQL Server.
If any such functionality is required, a Hack can do the purpose
use the query
SET NOCOUNT ON
at the top of your select statement.
When SET NOCOUNT is ON, the count (indicating the number of rows affected by a Transact-SQL statement) is not returned.
When SET NOCOUNT is OFF, the count is returned. It is used with any SELECT, INSERT, UPDATE, DELETE statement.
The setting of SET NOCOUNT is set at execute or run time and not at parse time.
SET NOCOUNT ON mainly improves stored procedure (SP) performance.
Syntax:
SET NOCOUNT { ON | OFF }
I am using SQL Server 2008 Enterprise on Windows Server 2008 Enterprise. In a stored procedure, we can execute a SELECT statement directly. And it could also be executed in this new way, I am wondering which method is better, and why?
New method,
declare #teststatement varchar(500)
set #teststatement = 'SELECT * from sometable'
print #teststatement
exec (#teststatement)
Traditional method,
SELECT * from sometable
regards,
George
FYI: it’s not a new method, it is known as Dynamic SQL.
Dynamic SQL are preferred when we need to set or concatenate certain values into sql statements.
Traditional or normal way sql statements are recommended, because stored procedures are complied. Complied on first run "Stored Procedure are Compiled on First Run"
, execution plan of statements are being created at the time of compilation.
Dynamic sqls are ignored while creating execution plans, because it is taken as string (VARCHAR or NVARCHAR as declared).
Refer following articles for more details about dynamic query and stored procs
Introduction to Dynamic SQL Part 1
Introduction to Dynamic SQL Part 2
Everything you wanted to know about Stored Procedures
The traditional method is safer, because the query is parsed when you save it. The query in the 'exec' method is not parsed and can contain errors.
The "new" way, as mentioned, has nothing to do with SQL 2008. EXEC has been available for quite some time. It's also - in most cases - a Very Bad Idea.
You lose parameterization - meaning you are now vulnerable to SQL Injection. It's ugly and error-prone. It's less efficient. And it creates a new execution scope - meaning it can't share variables, temp tables, etc. - from it's calling stored proc.
sp_executesql is another (and preferred) method of executing dynamic SQL. It's what your client apps use, and it supports parameters - which fixes the most glaring problem of EXEC. However, it too has very limited use cases within a stored proc. About the only redeeming use is when you need a dynamic table or column name. T-SQL does not support a variable for that - so you need to use sp_executesql. The number of times you need or should be doing that are very low.
Bottom line - you'd be best off forgetting you ever heard of it.