Stored Procedure Results and Ad-Hoc Query Results in Single Request? - sql-server

I'm using plain ADO.NET to returns results from my SQL Server database.
I have a control that requires two sets of results. To make the control efficient, my plan was to send two queries in a single request to avoid multiple trips to the database, and use SqlDataReader.NextResult() to access the second set of results.
However, looking at the code, I see the first query is actually calling a stored procedure.
Is there any way to use ADO.NET to request the results from both a stored procedure and an ad-hoc query in a single request?

Yes you can, and exactly in the way you suggest. Set CommandType to Text, and CommandText to:
exec YourProcedure;
select * from YourTable;
You can use NextResult two move to the next resultset.

Related

Call stored procedure from SSIS Dataflow

The question in short:
Can I call a stored procedure that has an output parameter in a data flow?
In long:
I have many tables to extract, transform, and load from one db to another one.
Almost all of the tables require one transformation which is fixing the country codes (from 3 letters to two). So my idea is as follows:
for each row: call the stored procedure, pass the wrong country code, replace the wrong code with the correct one (the output of the stored procedure)
There are at least two solutions for this:
Look-Up component: configuring it in advance mode and make sure the last sentence of the SProc is the Select statement that returns the good country code (e.g. SELECT #good_country_code)
Using an OLEDB Command
The latter (OLEDB Command) is actually quite simple, you need to configure it with:
EXEC ? = dbo.StoredProc #param1 = ?, #param2 = ?
As a consequence a #RETURN_VALUE will appear on the Available Destination Columns which you can then map to an existing column in the pipeline. Remember to create a new pipeline field/column (e.g. Good_Country_Code) using a Derived Column component before the OLEDB component and you'll have the chance to have both values, or replace the wrong one using another Derived Column component after OLEDB Command.
No, natively there isn't a component that is going to handle that. You can accomplish it with a Script Component but you don't want to.
What you're describing is a Lookup. The Data Flow Task has a Lookup Component but you'll be better served, especially for a finite list of values like Countries to push your query into the component.
SELECT T.Country3, T.Country2 FROM dbo.Table T;
Then you drag your SourceCountry column and match to Country3. Check Country2 and for all the rows that match, you'll get the 2 letter abbreviation.
A big disadvantage of trying to use your stored procedure is efficiency. The default Lookup is going to cache all those values. With the Script Version, say you have 10k rows come through, all with CAN. That's 10k invocations of your stored procedure where the results never change.
You do pay a startup cost as the default Lookup mode is Full Cache which means it's going to run your query and keep all those values local. This is great with your data set: 1000 countries max, 5 or 10 byte per row. That's nothing.
Yes, you can. You'll want to use a couple Execute SQL Tasks to do this.
Use an Execute SQL Task to gather a Result Set of Wrong_Country_Codes.
Add a ForEach Container as a successor to the previous Execute SQL Task. Pass the Result Set to this Container.
Inside that ForEach container, you will have another Execute SQL Task that will call your sproc, using each row (e.g. Wrong_Country_Code) as a variable parameter.
That should work. Only select the columns necessary to pass to your stored procedure.
Edit
In acknowledgement to the other answer, performance is going to be an issue. Perhaps rather than have the stored procedure produce an output, alter the sproc to do the updates for you.

Inline SQL versus stored procedure

I have a simple SELECT statement with a couple columns referenced in the WHERE clause. Normally I do these simple ones in the VB code (setup a Command object, set Command Type to text, set Command Text to the Select statement). However I'm seeing timeout problems. We've optimized just about everything we can with our tables, etc.
I'm wondering if there'd be a big performance hit just because I'm doing the query this way, versus creating a simple stored procedure with a couple params. I'm thinking maybe the inline code forces SQL to do extra work compiling, creating query plan, etc. which wouldn't occur if I used a stored procedure.
An example of the actual SQL being run:
SELECT TOP 1 * FROM MyTable WHERE Field1 = #Field1 ORDER BY ID DESC
A well formed "inline" or "ad-hoc" SQL query - if properly used with parameters - is just as good as a stored procedure.
But this is absolutely crucial: you must use properly parametrized queries! If you don't - if you concatenate together your SQL for each request - then you don't benefit from these points...
Just like with a stored procedure, upon first executing, a query execution plan must be found - and then that execution plan is cached in the plan cache - just like with a stored procedure.
That query plan is reused over and over again, if you call your inline parametrized SQL statement multiple times - and the "inline" SQL query plan is subject to the same cache eviction policies as the execution plan of a stored procedure.
Just from that point of view - if you really use properly parametrized queries - there's no performance benefit for a stored procedure.
Stored procedures have other benefits (like being a "security boundary" etc.), but just raw performance isn't one of their major plus points.
It is true that the db has to do the extra work you mention, but that should not result in a big performance hit (unless you are running the query very, very frequently..)
Use sql profiler to see what is actually getting sent to the server. Use activity monitor to see if there are other queries blocking yours.
Your query couldn't be simpler. Is Field1 indexed? As others have said, there is no performance hit associated with "ad-hoc" queries.
For where to put your queries, this is one of the oldest debates in tech. I would argue that your requests "belong" to your application. They will be versionned with your app, tested with your app and should disappear when your app disappears. Putting them anywhere other than in your app is walking into a world of pain. But for goodness sake, use .sql files, compiled as embedded resources.
Select statement which is part of form clause of any
another statement is called as inline query.
Cannot take parameters.
Not a database object
Procedure:
Can take paramters
Database object
can be used globally if same action needs to be performed.

How really store procedure working

am used lot of time , i know the diff between sql query and sp ,
SQL query will be compiled everytime it is executed.
Stored procedures are compiled only once when they are
executed for the first time.
This is general database question
But one big doubt is ,
For example ,
one dynamic work , that is i pass the userid to SP and sp will return the username,password,full details,
So for this scenario the query should execute once again know, so what is the necessary of SP instead of SQL QUERY ,
Please clear this doubt ,
Hi thanks for all your updates,
but i dont want the advantage, comparison ,
just say ,
How sp executing , while we go with dynamic works,
For example ,
if pass userid 10 then sp also read records 10 ,
if i pass 14 then, SP again look the 14 records , see this same work NORMAL SQL QUERY
doing , but on that time execute and fetching ,so why should i go for sp ,
Regards
Stored procedures, like the name says, are stored on the database server. They are transmitted to the server and compiled when you create them, and executed when you call them.
Simple SQL queries, on the other hand, are transmitted to the server and compiled each time you use them.
So transmitting of a huge query (instead of a simple "execute procedure" command) and compiling create an overhead which can be avoided by the use of a stored procedure.
MySQL, like other RDBMS, has a query cache. But this avoid only compiling, and only if the query is exactly the same than a previously executed query, which means the cache is not used if you execute 2 times the same query, with different values in a where clause, for example.
I see no reason for a stored procedure simply to query for all user details.
Stored procedures are functional code that you execute on the database server. I can think of three reasons why you'd use them:
To create an interface for users that hides the schema details from clients.
Performance. Extensive calculations on a large data set might be done more efficiently on the database server
Sometimes it can be difficult (or impossible, depending on your skill) to express what you think you need in a declarative, set-based language like SQL. That's when some people throw up their hands and write stored procs.
Only 1. would be justifiable from your question. I would recommend sticking with SQL.
UPDATE: The new information you provided still does not justify stored procedures in my opinion. A query that returns 14 records is routine.

sql stored procedure clear resultsets

Can I clear the multiple result sets that a stored procedure has already gathered so that the next result set that is created becomes the very first result set returned by the procedure?
this would depend on the Database. In Sql Server, once the result set is sent, it is gone. The receiving application/code must deal with it. If you need to have logic like this, gather the results into a temp table and only return what is needed at the end of the procedure.
As KM said it depends a bit on the database. Can you explain how your stored procedure gather multiple result sets? Are you achieving this via multiple unions or by creating a dynamic sql statement ?

Returning a subset of a stored procedure

I have an application that (unfortunately) contains a lot of its business logic is stored procedures.
Some of these return masses of data. Occassionally the code will need a small amount of the data returned from the stored procedure. To get a single clients name, I need to call a stored procedure that returns 12 tables and 950 rows.
I am not able (due to project politics) to change the existing stored procedures or create a replacement stored procedure - the original massive procedure must be called as that contains the logic to find the correct client. I can create a new procedure as long as it uses the original massive procedure.
Is there anyway I can get SQL server to return only a subset, (a single table, or even better a single row of a single table) of a stored procedure?
I have to support sql server 2000 +
It is not possible to conditionally modify the query behaviour of a procedure whose source code you cannot change.
However, you can create a new procedure that calls the original then trims down the result. A SQL 2000 compatible way of doing this might be:
declare #OriginalResult table (
// manually declare every column that is returned in the original procedure's resultset, with the correct data types, in the correct order
)
insert into #OriginalResult execute OriginalProcedure // procedure parameters go here
select MyColumns from #OriginalResult // your joins, groups, filters etc go here
You could use a temporary table instead of a table variable. The principle is the same.
You will definitely pay a performance penalty for this. However, you will only pay the penalty inside the server, you will not have to send lots of unnecessary data over the network connection to the client.
EDIT - Other suggestions
Ask for permission to factor out the magic find client logic into a separate procedure. You can then write a replacement procedure that follows the "rules" instead of bypassing them.
Ask whether support for SQL 2000 can be dropped. If the answer is yes, then you can write a CLR procedure to consume all 12 resultsets, take only the one you want, and filter it.
Give up and call the original procedure from your client code, but find a way of measuring the performance drop, so that you can exert some influence on the decision-making backed up with hard data.
No, you can't. A stored procedure is a single executable entity.
You have to create a new stored proc (to return what you want) or modify the current one (to branch) if you want to do this: project politics can not change real life
Edit: I didn't tell you this...
For every bit of data you need from the database, call the stored procedure each time and use the bit you want.
Don't "re-use" a call to get more data and cache it. After all, this is surely the intention of your Frankenstein stored procedure to give a consistent contract between client and databases...?
You can try to make SQL CLR stored procedure for handle all tables returned by your stored procdure and
in C# code to find data you need and return what you need. But I think that is just is going to make things more complicated.
When you fill your dataset with sored procedure which return more results sets in data set you get for each
result set one DataTable.

Resources