SQL Stored procedure querying multiple tables syntax - sql

I am currently trying to create a stored procedure where it first grabs the RUId(Registered User ID) from the first table.And then uses this variable to query another table
The easiest way to explain this is by showing the a pseudo code of this request as shown below
create procedure GetRUIdForUser
#Email nvarchar (160)
AS
SELECT RUId From RegisteredUsers
WHERE Email = #Email
Then
Select * From OtherTable where Ruid = #Ruid
What would the correct syntax for this be or would this need to be split up into two separate stored procedures?
Thanks!

Why not simply use JOIN ? instead of multiple variable & select statements :
select t.*
from RegisteredUsers ru inner join
table t
on t.Ruid = ru.RUId
where ru.Email = #Email;
However, your query variable will have only one ruid which will not help you more. So, you need a table variable to hold all ruids instead.

Try this:
SELECT *
FROM OtherTable
WHERE Ruid = ( SELECT RUId
FROM RegisteredUsers
WHERE Email = #Email ) ;

I recommend a join but you need to declare a variable to use what you are trying to do.
create procedure GetRUIdForUser #Email nvarchar (160) as
declare #ruid int
SELECT #ruid = RUId From RegisteredUsers
WHERE Email = #Email
Select * From OtherTable where Ruid = #Ruid
My guess is that problem isn't as simple as you summarized.

Related

Combine sp result in select as column

I am trying to execute sp as sub query and treat result set of sp as column of outer query . Some thing like this
Select U.FirstName , (exec SomeSP ) as columnFromSP from User U
Is this possible i searched alot but found nothing on google.
Update
I cannot use #temp table because i am trying to do without #temp table
If you are able to convert your USP to a table value UDF, you will be use the UDF in your FROM statement.
CREATE FUNCTION dbo.SomeUDF
(
-- Add the parameters for the function here
#param varchar(1000)
)
RETURNS TABLE
AS
RETURN
(
SELECT #param as Value
)
GO
SELECT
a.Value,
'B' as Value2
FROM dbo.SomeUDF('ABC') a
Not possible, but you can work around it
Create a temp table & insert the results of the procedure into
it
Now join the User table with the temporary table and select the
columns you want from both tables
This assumes however, you have a joinable expression returned from the stored proc (one that you can match to a field in the user table). If the stored procedure on returns a single row, use a condition of 1=1 or something similar
-- Declare a temp table and column(for eg you have only 1 column)
CREATE TABLE #TEMP
(
FirstName VARCHAR(50)
)
-- The results after execution will be inserted to this table
INSERT INTO #TEMP
Exec SomeSP 'Params'
-- Select records from both tables in all combinations
SELECT U.FirstName , COL1 as columnFromSP
from User U
CROSS JOIN #TEMP

query in sql server for retrieving rows

I have a table that contains the following 4 columns:
id
name
lastname
phone
I want to write a stored procedure that gets an id as parameter, and then gets the name of that id and then use that name to get all the rows that their name is equal to the names that i found in last step!
here it is my query, i know it's wrong but i'm new to sql commands:
ALTER PROCEDURE dbo.GetAllNames
#id int
AS
select name as Name from Users where id = #id
-- i don't how to retrieve the names that are equal to Name
select * from Users where name = Name
can you correct my query and help me? Thanks.
SELECT by_name.name FROM Users AS by_id
join Users AS by_name ON by_id.name = by_name.name
where id = #id
You can simply say
SELECT * FROM users WHERE name in (SELECT name from users where id = #id)
This would handle the case where there are multiple records with the ID. If ID is a primary key, then you can replace the IN operator with =.
Try this :
ALTER PROCEDURE dbo.GetAllNames
#Id INT
AS
BEGIN
SELECT * FROM Users WHERE [Name] IN (SELECT [Name] FROM Users WHERE Id = #Id)
END
You can declare a variable #name where you can store the name....
ALTER PROCEDURE dbo.GetAllNames
#id int
AS
DECLARE #name nvarchar(50);
select #name =name from Users where id = #id;
select * from Users where name = #name;
I have just provide above solution as per your question style but I strongly recommend you to use JOIN in given scenario in following way:
SELECT b.name FROM Users a
INNER JOIN Users b
ON a.name = b.name
WHERE a.id = #id

Using variables in stored procedures

I am using Microsoft SQL server and writing a stored procedure that contains many select statements. Here I want two variables that hold results of two select statements, and I want to add those two variables to get final result. Please help me doing this (syntax and example).
Below is the syntax for SQL Server:
DECLARE #UserEmail Varchar(250)
DECLARE #LoginID INT
SET #UserEmail = 'a#b.org'
select #LoginID = LoginID from Login L
Where L.UserEmail = #UserEmail
You should clarify which DB you are using. In MS SQL Server, you can use temporary table variable like this:
BEGIN
SELECT product_id,product_name INTO #temp1 FROM products;
SELECT product_id,product_name INTO #temp2 FROM products;
SELECT * FROM #temp1
UNION
SELECT * FROM #temp2;
END
There are several types of temporary table variable in MS SQL Server.I've used one of them.To know more about this, just search "MS SQL Server Temporary tables" in web.
EDIT:
Here is another example with another type of temporary table variable in MS SQL Server.
DECLARE #temp1 TABLE (product_id INT,product_name VARCHAR(100));
DECLARE #temp2 TABLE (product_id INT,product_name VARCHAR(100));
INSERT INTO #temp1 SELECT product_id,product_name FROM products WHERE cat_id=1;
INSERT INTO #temp2 SELECT product_id,product_name FROM products WHERE cat_id=2;
SELECT product_id,product_name
FROM #temp1
UNION
SELECT product_id,product_name
FROM #temp2;

SQL Select Statement including SP Call has syntax error

MYTABLE has ID column. However, following query generates syntax error.
SELECT ID FROM MYTABLE
WHERE ID = EXEC MY_SP ID
What do you think is wrong here?
You can't call stored procedures inline like this.
A couple of options include:
1) Execute the stored procedure and store the results in a temp table. Then use that temp table.
e.g.
CREATE TABLE #Example
(
ID INTEGER
)
INSERT #Example
EXECUTE My_SP
SELECT t.ID FROM MyTable t JOIN #Example e ON t.ID = e.ID
DROP TABLE #Example
2) convert the sproc to a user defined function which you CAN call inline
e.g.
CREATE FUNCTION dbo.MyFunc()
RETURNS TABLE
AS
RETURN
(
SELECT ID FROM SomeTable WHERE ....
)
SELECT t.ID FROM MyTable t JOIN dbo.MyFunc() f ON t.ID = f.ID
3) If the sproc returns a single ID, consider returning an OUTPUT parameter from the sproc instead and use like this:
DECLARE #ID INTEGER
EXECUTE MY_SP #ID OUTPUT
SELECT ID FROM MYTABLE
WHERE ID = #ID
I don't think you need the exec statement, just call the sp, exec is expected to be a separate statement
I don't think you can do that at all. Are you perhaps thinking of a User Defined Function rather than a stored Procedure. Based on the context, you'll need a scalar UDF.
Try this:
SELECT ID FROM MYTABLE WHERE ID = ##SPID

SQL if( exists()) query duplication

I need to write a a query that gets a set of information from a table, but if there is no information for that specific client, then use the default set. I was wondering if there is a way to avoid query duplication in an if(exists()) statement.
For example:
IF( EXISTS( SELECT * FROM UserTable WHERE Name = #UserName))
BEGIN
SELECT * FROM UserTable WHERE Name = #UserName))
END
ELSE
BEGIN
SELECT * FROM UserTable WHERE Name = 'Jon Skeet'))
END
The first two selects (exists and the true part of the if) are the exact same. I want to avoid running the same query twice if the statement is true. I know the exists stops once the first true condition is met but that is still O(n) worst case.
Another option I know of, is put the information in a temp table and check if information is there, if not return the default information.
Both ways would work but what is the best way to do it? Are there other ways to do this? Is there some way to do this in the WHERE clause since that's the only thing that is different?
Edit: Fixed example to return a row not just a single item. So the answers of dumping the select to a single variable would be equal to a temp table I assume. Also, to not anger Jon Skeet, spelled his name right
You could do this:
SELECT TOP 1
UserID
FROM
UserTable
WHERE
Name IN (#UserName, 'John Skeet')
ORDER BY
CASE WHEN Name = 'John Skeet' THEN 2 ELSE 1 END
(or use LIMIT or whatever the method is for your RDBMS)
Or you could do this:
DECLARE #UserID INT
SELECT
#UserID = UserID
FROM
UserTable
WHERE
Name = #UserName
IF (#UserID IS NULL)
SELECT
#UserID = UserID
FROM
UserTable
WHERE
Name = 'John Skeet'
SELECT #UserID AS UserID
Or this:
SELECT
COALESCE(T2.UserID, T1.UserID)
FROM
UserTable T1
LEFT OUTER JOIN UserTable T2 ON
T2.Name = #UserName
WHERE
T1.Name = 'John Skeet'
Or this:
SELECT
UserID
FROM
UserTable
WHERE
Name = #UserName
IF (##ROWCOUNT = 0) -- MS SQL Server specific, your RDBMS method will vary
SELECT
UserID
FROM
UserTable
WHERE
Name = 'John Skeet'
How about:
DECLARE #UserID int;
SELECT #UserID = UserID FROM UserTable WHERE Name = #UserName
IF(#UserID IS NULL)
BEGIN
SELECT #UserID=UserID FROM UserTable WHERE Name = 'Jon Skeet'))
END
SELECT #UserID
You can select into a variable check the variable if it comes back null run the get default query
something like this:
Declare #uID int;
SELECT #uID = UserID FROM UserTable WHERE Name = #UserName
IF (#uID is null)
begin
'Select default here'
End
select #uID
If you are concerned about performance, I think you probably don't need to be - most DBMSes should optimize away the duplication. If you are still concerned about performance, run it both ways to see if your DBMS has any problem with it.
If you're concerned about code - maintainability of duplicate code sections, readability, and the like, then study the above answers with that in mind. You may find that the duplication is your least-worst option. It's a shame SQL isn't more malleable.
You don't say what DBMS you are using, but it clearly isn't Oracle (which is the one I know). However, I would expect your DBMS would allow you to do something like this pseudo-code:
SELECT UserID FROM UserTable WHERE Name = #UserName
IF <no data returned by that>
BEGIN
SELECT UserID FROM UserTable WHERE Name = 'John Skeet'
END
In Oracle this would be:
BEGIN
SELECT UserID INTO v_UserID FROM UserTable WHERE Name = :UserName;
EXCEPTION
WHEN NO_DATA_FOUND THEN
SELECT UserID INTO v_UserID FROM UserTable WHERE Name = 'John Skeet';
END
Unless you are going to define a set of variables for each field you are returning (and it's only one record) I think the most efficent way is to make the call twice. The temp table would probably cost more.