SQL Server 2005: Call a stored procedure from a WHERE clause - sql-server-2005

I need to make a SELECT with a call of a stored procedure in the WHERE clause.
It should be something like that....
SELECT distinct top 10 i.x, d.droit
FROM v_droit d, v_info i
WHERE d.nomdroit='yy'
AND i.id<>2
AND (select val from (exec up_droits(i.x, d.droit)) <>3
But it does not work...
Any idea?
Don't say to replace the stored procedure with a function because is not possible to use the existing code in a function. So the function is not a valid option. I really need to be able to use a stored procedure

This is achieved by first executing the stored procedure, capturing the output into a #temp table or a #tabel variable, then running your query against the table. Something like this:
declare #droits_table (val ,... );
insert into #droits_table
exec up_droits(param, param);
SELECT distinct top 10 i.x, d.droit FROM v_droit d, v_info i WHERE d.nomdroit='yy' AND i.id<>2 AND (select val from #droits) <>3
Of course this will not work for you because the up_droits needs the i.x and d.droit parameters from the query. This indicates that your stored procedure should probably be a a view or table valued function.

Sorry but, make it a table valued function rather than stored procedure.
Eg:
Scalar - SELECT id, name FROM test WHERE id < (SELECT dbo.mytestfunction())
Table - SELECT id, name FROM test WHERE id = (SELECT col1 from dbo.mytestfunction())

You can't. The content of the WHERE clause must be a search expression.

Is the reason that the code doesn't work as a function because it modifies some data? If so, then you're out of luck, functions used in where clauses must be immutable.
If the stored procedure doesn't modify any data, you may be able to wrap it inside of a function.

If you are on SQL Server I don't think you can do what you propose.
But one thing you can do is build dynamic queries, but be careful doing it because they open up many interesting problemareas.
The syntax is :
EXEC #<query>
But anotherthing you can do, which is probably much better for you, is to make the up_droits function deliver it's results in a temp table, if you select into a #table it is temporary for the duration of your function/procedure scope
declare procedure up_droits() as
select val .. into #temp
So what you do is create a procedure
create procedure Top10FromDroit
begin
exec up_droits
SELECT distinct top 10 i.x, d.droit FROM v_droit d, v_info i WHERE d.nomdroit='yy' AND i.id2 AND (select val from (#temp) 3
Hopefully that will give you the results you want to achieve.
If at first you don't succeed, code around it^^

Could anyone of you explain reasons for executing dynamic SQl inside stored procedure. I know very few situations when you need them - but really very few. 99.9% (or 999 of a 1000) of execute strings could be rewritten as normal sql statements with parameters.
The very same is with Selects that have functions inside select or where clauses.
Try to think about your sets of data, not about procedural ways how to solve it.

Related

Using results of one stored procedure in another stored procedure - SQL Server

Is there any way to use the results of one stored procedure in another stored procedure without using a table variable or temp table? The logic is as follows:
IF (#example = 1)
BEGIN
DECLARE #temp TABLE (Id INT);
INSERT INTO #temp
EXEC [Procedure1] #ItemId = #StockId
set #Cost = (select top 1 id from #temp)
Ideally i would like to know if there is a way to do this without having to use a temp table. Looked around online but can't find anything that works. Any advice would be great.
In general, if you want to use user-defined code in a SELECT, then it is better to phrase the code as a user-defined function rather than a user-defined procedure.
That is, procedures should be used for their side effects and functions should be used for their return values.
That said, you can use openquery (documented here) to run an exec on a linked server. The linked server can be the server you are running on.

SELECT Query selecting values based on a value in another table

I have 2 tables
Account(AccountId, Encoding)
DeviceAccountMap(AccountId, DeviceId)
Now I need to fetch the devices from the DeviceAccountMap. I pass a list of AccountId to a stored procedure and while fetching the DeviceId from the DeviceAccountMap table I need to compare the Encoding value for each account with a particular value.
Which is the easy way to do this? I am totally lost.
The select clause in the stored procedure will look something like this:
DECLARE #Accounts [usp].[Array]
and [usp].[Array] is defined as below
CREATE TYPE [usp].[Array] AS TABLE
(
Value VARCHAR(36) NULL
)
SELECT
DeviceId,
AccountEncoding = A.Encoding
FROM
usp.DeviceControllerAccountMap DCAM
INNER JOIN
usp.Account A ON (DCAM.AccountId = A.AccountId)
WHERE
DCAM.AccountId IN (SELECT Value From #AccountIds)
AND DCAM.IsShared = 1
AND AccountEncoding LIKE A.Encoding + '.%'
In other words I need to fetch the encoding value for each account and use that in this where clause.
So you can look up information on Table-Valued Parameters (TVPs) in T-SQL.
Here is an article by Erland Sommarskog.
You can refer to this StackOverflow answer to see an example of C# code calling a stored procedure that uses a TVP. I believe TVPs require SQL Server 2008 or higher.
TVPs, as far as I understand, provide a way to make your own data type in sql server that gets treated as if it was a table. You're doing this when you declare your Array type and then when you use the #AccountIds in your stored procedure's select statement.
CREATE TYPE [usp].[Array] AS TABLE -- maybe choose a more descriptive name than 'Array'
(
Value VARCHAR(36) NULL -- choose a more descriptive name than 'Value'
)
CREATE PROCEDURE [usp].[your_procedure_name]
#AccountIds [usp].[Array] READONLY -- use TVP as a parameter
AS
SELECT …
It is not clear form your question details whether you also mean to have a parameter in the stored procedure for the Encoding. It seems like you're looking for accounts whose Encodings start with a period '.'.
So first, create your type, like you're doing.
Then create your stored procedure.
Then test your stored procedure, something like this:
DECLARE #mylist Array -- make TVP sample data
INSERT #mylist(Value) VALUES(1),(11),(27),(123) -- insert some values
exec your_procedure_name #mylist -- run stored procedure
The following line is completely unnecessary. The JOIN to Account does this filter for you.
DCAM.AccountId IN (SELECT Value From #AccountIds)
Or am I missing something?

Create parameterized VIEW in SQL Server 2008

Can we create parameterized VIEW in SQL Server 2008.
Or Any other alternative for this ?
Try creating an inline table-valued function. Example:
CREATE FUNCTION dbo.fxnExample (#Parameter1 INTEGER)
RETURNS TABLE
AS
RETURN
(
SELECT Field1, Field2
FROM SomeTable
WHERE Field3 = #Parameter1
)
-- Then call like this, just as if it's a table/view just with a parameter
SELECT * FROM dbo.fxnExample(1)
If you view the execution plan for the SELECT you will not see a mention of the function at all and will actually just show you the underlying tables being queried. This is good as it means statistics on the underlying tables will be used when generating an execution plan for the query.
The thing to avoid would be a multi-statement table valued function as underlying table statistics will not be used and can result in poor performance due to a poor execution plan.
Example of what to avoid:
CREATE FUNCTION dbo.fxnExample (#Parameter1 INTEGER)
RETURNS #Results TABLE(Field1 VARCHAR(10), Field2 VARCHAR(10))
AS
BEGIN
INSERT #Results
SELECT Field1, Field2
FROM SomeTable
WHERE Field3 = #Parameter1
RETURN
END
Subtly different, but with potentially big differences in performance when the function is used in a query.
No, you cannot. But you can create a user defined table function.
in fact there exists one trick:
create view view_test as
select
*
from
table
where id = (select convert(int, convert(binary(4), context_info)) from master.dbo.sysprocesses
where
spid = ##spid)
...
in sql-query:
set context_info 2
select * from view_test
will be the same with
select * from table where id = 2
but using udf is more acceptable
As astander has mentioned, you can do that with a UDF. However, for large sets using a scalar function (as oppoosed to a inline-table function) the performance will stink as the function is evaluated row-by-row. As an alternative, you could expose the same results via a stored procedure executing a fixed query with placeholders which substitutes in your parameter values.
(Here's a somewhat dated but still relevant article on row-by-row processing for scalar UDFs.)
Edit: comments re. degrading performance adjusted to make it clear this applies to scalar UDFs.
no. You can use UDF in which you can pass parameters.

MySQL - Using stored procedure results to define an IN statement

I'd like to use a stored procedure to define the IN clause of a select statement.
This is (a simplified version of) what I'm trying to do:
SELECT *
FROM myTable
WHERE columnName IN (CALL myStoredProc)
myStoredProc performs some complicated logic in the database and returns a list of possible matching values for columnName. The statement above does not work obviously. The select statement may be performed in another stored procedure if that makes a difference.
Is this at all possible in mySQL?
What return type does your current stored procedure have? You are speaking of "a list", so TEXT?
Maybe there's an easier way, but one thing you can do (inside another stored procedure) is to build another query.
To do that, we need to work around two limitations of MySQL: a) To execute dynamic SQL inside a stored procedure, it needs to be a prepared statement. b) Prepared statements can only be created out of user variables. So the complete SQL is:
SET #the_list = myStoredProc();
SET #the_query = CONCAT('SELECT * FROM myTable WHERE columnName IN (' , #the_list , ')');
PREPARE the_statement FROM #the_query;
EXECUTE the_statement;
If you're talking about returning a result set from a stored routine and then using it as table, that is not possible. You need to make a temporary table to work around this limitation.

Combine stored procedure and query in T-SQL

How do I combine executing of a stored procedure and using its result or parameters in a regular SQL query?
For example I would like to do something like the following:
-- passing result of SELECT to SP
SELECT a, b FROM t
EXEC my_sp a, b
-- passing result of SP to INSERT
INSERT INTO t
EXEC my_sp a, b
etc.
no, you need to use a temp table
create table #results (col1 int, col2 varchar(5) ...)
INSERT INTO #results
EXEC YourProcedure #parma...
then you can join to it
SELECT
*
FROM YourTable y
JOIN #results r ON ...
....
if you don't know the columns and data types from the procedure you can use this excellent answer: Insert results of a stored procedure into a temporary table
In brief it uses OPENROWSET to execute the stored procedure into a #temp table that is created on the fly, without the need to name and know the type all the columns.
If your SP can be rewritten as an inline table valued UDF, these typically perform very well and are equivalent to a parametrized view. ITVF can be used any place you would use a table or view.
If your SP won't work as an inline TVF (local variable manipulation required), it may work as a multi-statement TVF (contains a BEGIN/END) which may or may not perform poorly depending on what you have to do.
After your SP has been turned into a UDF, you can then still call the UDF from your SP (SELECT* FROM udf(params)) or elsewhere it can be used for joins, etc, so all your code is inside the UDF - no duplication.