How to return table from T-SQL Stored Procedure - sql

SQL Newbie here, and I'm having a hell of a time finding what should be a simple code example to answer what I think is a simple question.
I need to write a stored procedure that does three things in order:
1) Select rows from one table
2) Update rows in another table, using values from the results table in #1
3) Return the results table from #1.
What I can't find is any example about how to return a value like this from a stored procedure. Also, how to retrieve that returned table from the caller (which is another T-SQL script).

Have a look at this.
DECLARE #Table1 TABLE(
ID INT,
VAL int
)
INSERT INTO #Table1 (ID,VAL) SELECT 1, 1
INSERT INTO #Table1 (ID,VAL) SELECT 2, 2
INSERT INTO #Table1 (ID,VAL) SELECT 3, 3
DECLARE #Table2 TABLE(
ID INT,
VAL VARCHAR(MAX)
)
INSERT INTO #Table2 (ID,VAL) SELECT 1, 1
INSERT INTO #Table2 (ID,VAL) SELECT 2, 2
INSERT INTO #Table2 (ID,VAL) SELECT 3, 3
--Lets say this is the 2 tables
--now this will go into the sp
UPDATE #Table1
SET Val = t1.Val + t2.Val
FROM #Table1 t1 INNER JOIN
#Table2 t2 ON t1.ID = t2.ID
SELECT t1.*
FROM #Table1 t1 INNER JOIN
#Table2 t2 ON t1.ID = t2.ID
--and you can insert into a var table in the tsql script that calls the sp
DECLARE #Table1TSQL TABLE(
ID INT,
VAL int
)
INSERT INTO #Table1TSQL (ID,VAL) EXEC YourSP

Related

conditional union multiple tables

This is based on union tables on value
declare #t1 table (val int,datatype1 int,datatype2 int ,datatype3 int)
declare #t2 table (val int,datatype1 int ,datatype2 int ,datatype3 int )
declare #t3 table (val int,datatype1 int ,datatype2 int ,datatype3 int )
insert into #t1 values (10,1,0,0),(31,1,0,0),(20,1,0,0)
insert into #t2 values (31,0,1,0),(4,0,1,0)
insert into #t3 values (31,0,0,1),(5,0,0,1);
Below is the changes in requirement(case):
1. need to union #t1,#t2 & #t3
(if same value exist #t1 & #t2 multiple rows and #t2 & t3 only 1 row)
2. if any duplicate value (there is no chance dup in same table)
i) suppose 31 in #t1 , 31 in #t2 then multiple rows are allowed
ii) suppose 31 in #t2 & #t3 then only one records i.e #t3 updated to #t2
iii) if 31 in #t1 ,#t2,#t3 only 2 records i.e #t1,#t2 records with #t3 details updated to #t2 records
Now i) & iii) are working fine
select val,
max(datatype1) datatype1,
max(datatype2)datatype2,
max(datatype3)datatype3
from (
select 't1' AS tab_name, * from #t1
union all
select 't2' AS tab_name,* from #t2
union all
select 't3' AS tab_name,* from #t3
) as data
group by val, CASE WHEN tab_name in ('t2') THEN 1 END
order by val;
But Current Result showing multiple records for case 2 also any help
Expected Result:
Your question is very hard to follow. I'm a bit lost on the conditions, but this rather simple query returns the results that you specify:
select val,
max(datatype1) as datatype1,
max(datatype2) as datatype2,
max(datatype3) as datatype3,
max(datatype4) as datatype4
from (select 't1' AS tab_name, t1.* from t1
union all
select 't2' AS tab_name, t2.* from t2
union all
select 't3' AS tab_name, t3.* from t3
) data
group by val;
Here is a db<>fiddle.
I wonder if the culmination of all your results is a relatively simple aggregation.

Update statement with Where Not Exists

I am trying to do the following:
Set the status column to 1 when the row in the first table (variable) does not exist in the second one.
I tried this:
update #table1
set status=1
where NOT EXISTS (select top 1 1 from #table2 where #table1.foo=#table2.foo)
But this doesn't even compile, not recognizing #table1 in the Where statement.
Must declare the scalar variable "#table1".
Any clue about this?
Your approach is fine. You just need table aliases because the # is used to in SQL Server to represent variables (scalars or tables) and is hence problematic for aliases:
update t1
set status = 1
from #table1 t1
where not exists (select 1 from #table2 t2 where t2.foo = t1.foo);
Note that the top 1 is unnecessary in the subquery.
You can do this kind of thing by joining the two tables with a LEFT JOIN and checking the right side for NULL:
UPDATE t1
SET t1.status=1
FROM #table1 t1
LEFT JOIN #table2 t2
ON t1.foo = t2.foo
WHERE t2.foo IS NULL
The specific error you got is because you haven't got a statement declaring #table1 as a table variable, like DECLARE #table1 TABLE (foo int) for example. If table1 is not a variable, you don't need the #.
no need any top inside scaler query
update #table1
set status=1
where NOT EXISTS (select 1 from #table2 where #table1.foo=#table2.foo)
cause exists return boolean
you could use below query
update #table1
set status=1
where #table1.foo not in ( select foo from #table2 where foo is not null)
There are multiple ways - inner query with NOT IN and NOT EXISTS and JOIN query:
update tab1 set status = 1 where name not in (select name from tab2);
update tab1 set status = 1 where not exists (select 1 from tab2 where tab1.name=tab2.name);
update tab1 set status = 1 from tab1 left outer join tab2 on tab1.name = tab2.name where tab2.name is null;
Sample schema to run above queries;
create table tab1(name varchar(30), status int);
create table tab2(name varchar(30));
insert into tab1 values('a', 5);
insert into tab1 values('b', 6);
insert into tab1 values('c', 7);
insert into tab1 values('d', 8);
insert into tab2 values('a');
insert into tab2 values('d');
You have to declare table1 and table2 variables
DECLARE #table1 YOUR_TABLE1_NAME;
DECLARE #table2 YOUR_TABLE2_NAME;
update #table1
set status=1
where NOT EXISTS (select top 1 from #table2 where #table1.foo=#table2.foo)
You should use alias name for both table.
DECLARE #TABLE_1 TABLE (DEPT_NAME VARCHAR(50),DEP_ID INT)
INSERT INTO #TABLE_1(DEPT_NAME,DEP_ID)
SELECT 'IT',1 UNION ALL
SELECT 'HR',2 UNION ALL
SELECT 'ACCOUNT',3 UNION ALL
SELECT 'ADMIN',4 UNION ALL
SELECT 'SALES',5 UNION ALL
SELECT 'CEO',7
DECLARE #TABLE_2 TABLE (E_ID INT,EMP_NAME VARCHAR(50),DEP_ID INT)
INSERT INTO #TABLE_2(E_ID,EMP_NAME,DEP_ID)
SELECT 1,'JHON',1 UNION ALL
SELECT 2,'LITA',2 UNION ALL
SELECT 3,'MATT',1 UNION ALL
SELECT 4,'JEFF',1 UNION ALL
SELECT 5,'BROCK',2 UNION ALL
SELECT 6,'BOB',5 UNION ALL
SELECT 7,'SAM',4 UNION ALL
SELECT 8,'DAVID',3 UNION ALL
SELECT 9,'JACK',1 UNION ALL
SELECT 10,'GARY',4 UNION ALL
SELECT 11,'DONALD',6
SELECT * FROM #TABLE_1 A WHERE NOT EXISTS (SELECT DEP_ID FROM #TABLE_2 B WHERE A.DEP_ID=B.DEP_ID )

How to combine two MS SQL Server tables into one in a stored procedure

I have a stored procedure in SQL Server 2008R2 that takes two user defined table types as parameters. Each of these types is a simple table holding an series of Ids:
CREATE TYPE [dbo].[Ids] AS TABLE(
[Id] [int] NULL
)
I want to combine the two parameters passed in to achieve the following result:
DECLARE
#Table1 TABLE (Id INT )
DECLARE
#Table2 TABLE (Id INT )
INSERT INTO #Table1 VALUES (1)
INSERT INTO #Table1 VALUES (2)
INSERT INTO #Table2 VALUES (11)
INSERT INTO #Table2 VALUES (22)
SELECT * FROM #Table1
SELECT * FROM #Table2
DECLARE
#Combined TABLE (T1 INT, T2 INT)
-- TODO: Magically combine the two tables
SELECT * FROM #Combined
-- Output would be the following
1, 11
1, 22
2, 11
2, 22
You seem to want a cross join:
insert into #Combined(t1, t2)
select t1.id, t2.id
from #Table1 t1 cross join
#Table2 t2;

Join without foreign key for condition

I get two tables like this:
create table #table1 (data1 int)
create table #table2 (data2 int)
insert into #table1 (data1) values (1),(2),(3)
insert into #table2 (data2) values (4),(5),(6)
I want to make a query, that returns two columns like this:
data1 data2
1 4
2 5
3 6
I found one solution for this:
select t1.data1, t2.data2 from
(select row_number() over (order by data1) as [Index], data1 from #table1) as t1 inner join
(select row_number() over (order by data2) as [Index], data2 from #table2) as t2 on (t1.[Index] = t2.[Index])
Do you know other ways to join tables (any joins except cross) without keys?
EDIT: I look for solution without cursor and temporary tables.
create table table1 (data1 int)
create table table2 (data2 int)
insert into table1 (data1) values (1),(2),(3)
insert into table2 (data2) values (4),(5),(6)
create table #table1
(id int identity(1,1),
data1 int)
create table #table2
(id int identity(1,1),
data2 int)
insert into #table1 (data1) select data1 from table1
insert into #table2 (data2) select data2 from table2
create table table3
(data1 int,
data2 int)
insert into table3 (data1, data2)
select #table1.data1, #table2.data2
from #table1
inner join #table2 on #table1.id = #table2.id
what will be output in this case if i insert below values
insert into #table1 (data1) values (1),(2),(3)
insert into #table2 (data2) values (2),(3),(4)
may you need
select t1.data1, t2.data2 from t1,t2

SQL intersect with other tables, how do I ignore it?

I am trying to run a query given three tables.
DECLARE #TABLE1 TABLE (ID CHAR(2))
DECLARE #TABLE2 TABLE (ID CHAR(2))
DECLARE #TABLE3 TABLE (ID CHAR(2))
INSERT INTO #TABLE1 VALUES('1')
INSERT INTO #TABLE1 VALUES('2')
INSERT INTO #TABLE2 VALUES('1')
--NOTHING in TABLE3
I Need to get only the values that are present and ignore the null table. This doesn't work since TABLE3 has no values.
SELECT ID
FROM #TABLE1
INTERSECT
SELECT ID
FROM #TABLE2
INTERSECT
SELECT ID
FROM #TABLE3
**Result should be 1**
How do I ignore the any table if it's null but keep the other values?
Why not do a union of select distincts from each table, and then group that by ID and select count(*), and select only rows with count(*) equal to the maximum value of count(*) in the result?
It's a bit of a mess of subqueries at this point unfortunately but you should get the logic :)
Intersect is not going to work for you as you can't add conditions to it.
From what I understand you want to select all records where the ID appears in at least 2 of the tables. I am assuming that the ID is unique to each table.
The following works in MS SQL Server:
DECLARE #TABLE1 TABLE (ID CHAR(2))
DECLARE #TABLE2 TABLE (ID CHAR(2))
DECLARE #TABLE3 TABLE (ID CHAR(2))
INSERT INTO #TABLE1 VALUES('1')
INSERT INTO #TABLE1 VALUES('2')
INSERT INTO #TABLE2 VALUES('1')
--NOTHING in TABLE3
;WITH AllValues AS
(
SELECT ID
FROM #TABLE1
UNION ALL
SELECT ID
FROM #TABLE2
UNION ALL
SELECT ID
FROM #TABLE3
)
SELECT ID
FROM AllValues
GROUP BY ID
HAVING COUNT(*) > 1
Maybe... But the design of the system is extremely foreign; a real world example would help understand what you're trying to do.
Select count(*), ID FROM (
Select ID from #table1
UNION
Select ID from #table2
UNION
Select ID from #table3) Derived
Where RowNum =1
GROUP BY ID
ORder by count(*) DESC
Updated where clause was in wrong place