SQL stored proc using where in statement - sql-server

I am trying to inserting data from a table to another table. But I need using multiple specific IDs in where clause. And, I need to define these IDs while running the proc. The query is below,
CREATE PROCEDURE insert_hh
#id int
AS
BEGIN
SET IDENTITY_INSERT test_HH ON
INSERT INTO test_HH
(ID,Beneficiary_Name,Family_Members,
[M_50_yrs],
[F_50_yrs],
[M_50_18],
[F_50_18],
[M_18_15],
[F_18_15],
[M_15_5],
[F_15_5],
[M_5_2],
[F_5_2],
[M_2],
[F_2],
Beneficiary_Status,
Reason_of_Rejection)
SELECT ID,Beneficiary_Name,Family_Members,
[M_50_yrs],
[F_50_yrs],
[M_50_18],
[F_50_18],
[M_18_15],
[F_18_15],
[M_15_5],
[F_15_5],
[M_5_2],
[F_5_2],
[M_2],
[F_2],
Beneficiary_Status,
Reason_of_Rejection
FROM HH
WHERE ID IN ((#id))
SET IDENTITY_INSERT test_HH OFF
END
For now, I can insert only one ID for each time. Can you help me to insert multiple IDs in the same proc?
Thanks.

For multiple value change #Id parameter of stored procedure to VARCHAR with desired length.
CREATE PROCEDURE insert_hh
#id varchar(max)
AS
SET #Id = '1,10,20,30'
-- temp table
DECLARE #Id_tbl TABLE ( Id INT )
INSERT INTO #Id_tbl
SELECT
LTRIM(RTRIM(split.a.value('.', 'NVARCHAR(MAX)'))) AS fqdn
FROM
(SELECT
CAST ('<M>' + REPLACE(#Id, ',', '</M><M>') + '</M>' AS XML) AS data ) AS a
CROSS APPLY data.nodes ('/M') AS split(a)
-- INSERT STATEMENT
SELECT <Fields> FROM
<Your Table>
WHERE
ID IN (SELECT Id FROM #Id_tbl)
END
GO

CREATE PROCEDURE insert_hh
#id NVARCHAR(MAX)
AS
BEGIN
SET IDENTITY_INSERT test_HH ON
INSERT INTO test_HH
(ID,Beneficiary_Name,Family_Members,[M_50_yrs],[F_50_yrs],[M_50_18],[F_50_18],
[M_18_15],[F_18_15],[M_15_5],[F_15_5],[M_5_2],[F_5_2],[M_2],[F_2],
Beneficiary_Status,Reason_of_Rejection)
SELECT ID,Beneficiary_Name,Family_Members,[M_50_yrs],[F_50_yrs],[M_50_18],
[F_50_18],[M_18_15],[F_18_15],[M_15_5],[F_15_5],[M_5_2],[F_5_2],[M_2],[F_2],
Beneficiary_Status,Reason_of_Rejection
FROM HH
CROSS APPLY STRING_SPLIT(#id, ',')
WHERE HH.ID = value
SET IDENTITY_INSERT test_HH OFF
END
modelling fiddle
Pay attention - the parameter datatype is changed.

Related

Temp table value in where clause of Dynamic SQL

Need to know whether below Syntax is correct while using a value from temp table in where clause of dynamic SQL
DECLARE #sqlQ nvarchar(1000);
if OBJECT_ID('tempdb..#Tem') is not null BEGIN DROP tABLE #Tem END
create table #Tem
(order nvarchar(10))
insert into #Tem
Select orderID from customerdetails where OrderID >100
SET #sqlQ = N'UPDATE FINALTable SET Highvalcusomer=1 where
orderno=#Tem.order'
EXEC #sqlQ
Just do it in one go
UPDATE
FINALTable
SET
Highvalcusomer=1
where
orderno IN (Select orderID from customerdetails where OrderID >100)
Or if you really want to use dynamic SQL
SET #sqlQ = N'UPDATE FINALTable SET Highvalcusomer=1 where
orderno IN (Select orderID from #Tem)'
EXEC (#sqlQ )
#Tem will be in scope for the dynamic SQL

Issue with splitting values and passing to a stored procedure

Iam getting the below input parameter values in one of the stored procedure.
#DocKey1, #DocValue1,
#DocKey2, #DocValue2,
#DocKey3, #DocValue3,
#DocKey4, #DocValue4,
#DocKey5, #DocValue5
From this procedure iam calling another procedure to insert each pair of values.
Right now am calling the InsertDocValues stored procedure multiple times to insert each pair.
exec InsertDocValues #DocKey1, #DocValue1
exec InsertDocValues #DocKey2, #DocValue2
exec InsertDocValues #DocKey3, #DocValue3
exec InsertDocValues #DocKey4, #DocValue4
exec InsertDocValues #DocKey5, #DocValue5
Is there anyway i can pass the complete set of values to another procedure as below and then split each pair and insert
eg: #DocKey1, #DocValue1 and #DocKey2, #DocValue2 etc
#DocKey1, #DocValue1, #DocKey2, #DocValue2, #DocKey3, #DocValue3, #DocKey4, #DocValue4, #DocKey5, #DocValue5
Below is the procedure am using now to insert
Create PROCEDURE [dbo].[InsertDocValues]
(
#DocKey varchar(20),
#DocValue nvarchar(20)
)
AS
SET NOCOUNT ON;
BEGIN
INSERT INTO dbo.DocValues(
DocKey,
DocValue
)
VALUES(
#DocKey,
#DocValue
)
End
Please suggest
May be the below code would work for you.
Using user defined table type variable.
CREATE TYPE DocTable AS TABLE
(
DocKey int,
DocValue nvarchar(50)
);
GO
And then use this type to create required variable in first SP and pass the same to your second SP.
DECLARE #DocTable AS DocTable;
INSERT INTO #DocTable
SELECT #DocKey1, #DocValue1 UNION ALL
SELECT #DocKey2, #DocValue2 UNION ALL
SELECT #DocKey3, #DocValue3 UNION ALL
SELECT #DocKey4, #DocValue4 UNION ALL
SELECT #DocKey5, #DocValue5
You can create the above insert query dynamically also. There are so many ways to populate a table. So, use any one as you are getting output from your first SP.
And then call your Second SP.
EXEC [dbo].[InsertDocValues] #DocTable
Changes in second SP would be look like this.
Create PROCEDURE [dbo].[InsertDocValues]
(
#DocTable DocTable READONLY
)
AS
SET NOCOUNT ON;
BEGIN
INSERT INTO dbo.DocValues(
DocKey,
DocValue
)
SELECT
DocKey,
DocValue
FROM #DocTable
END
I'm getting the sense you have a string of pairs (key,value). Perhaps something like this:
Example
Declare #List varchar(max) = 'Key1:Value1,Key2:Value2'
Insert Into dbo.DocValues(DocKey,DocValue )
Select DocKey = left(RetVal,charindex(':',RetVal+':')-1)
,DocVal = stuff(RetVal,1,charindex(':',RetVal+':'),'')
From (
Select RetSeq = row_number() over (Order By (Select null))
,RetVal = ltrim(rtrim(B.i.value('(./text())[1]', 'varchar(max)')))
From (Select x = Cast('<x>' + replace((Select replace(#List,',','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A
Cross Apply x.nodes('x') AS B(i)
) A
The Data Inserted would be
DocKey DocVal
Key1 Value1
Key2 Value2

Select (Select field from FieldTable) from Table

I'm using MSQL 2005. I have 2 table.A and B
Table A
- ID DOVKOD
- 1 KURSATIS
Table B
- ID KURALIS KURSATIS
- 1 2,2522 2,2685
- 2 2,4758 2,4874
Table A has only 1 record
When I execute Select (Select DOVKOD from Table A) from Table B I want to get same result as Select KURSATIS from Table B
I am gonna use it in a view. How can I do that. Thanks..
You can simply use a CASE expression:
SELECT CASE WHEN (SELECT DOVKOD FROM A) = 'KURSATIS' THEN KURSATIS
ELSE KURALIS
END
FROM B
SQL Fiddle Demo here
You must use Dynamic TSQL
SELECT #column=DOVKOD from Table A
EXEC ('Select ' + #column + ' from Table B')
If I understood you right then in table A you have the name of the column that you want to return. Then your solution is bad at all. I'll rather do something like that:
CREATE TABLE #TableA
(
ID INT, DOVKOD VARCHAR(100)
);
INSERT INTO #TableA VALUES (1, 'KURSATIS');
CREATE TABLE #TableB
(
ID INT, Value DECIMAL (18,2),Name VARCHAR(100)
);
INSERT INTO #TableB VALUES (1, 2.2522 , 'KURALIS');
INSERT INTO #TableB VALUES (2, 2.4758 , 'KURSATIS');
SELECT #TableB.* FROM #TableB JOIN #TableA ON #TableA.DOVKOD = #TableB.Name
The only way how to do this in MySQL is using Prepared statements. Dynamic pivot tables (transform rows to columns) is a good article about this.
SET #sql = NULL;
Select DOVKOD INTO #sql
FROM from Table A;
SET #sql = CONCAT('SELECT ', #sql, 'FROM Table B');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

jdbc sql error: statement did not return a result set

I have two stored procedures as follows:
create stored procedure p1
as
select * from table1 where datediff(day, table1.[date], getdate())
create stored procedure p2
as
declare #t1 table(
ref varchar(20)
)
insert into #t1 select * from table1 where ref = 'some ref'
declare #t2 table(
fname varchar(20),
lname varchar(20),
email varchar(1000)
)
declare #len int = (select count(ref) from #t1)
while #len > 0
begin
declare #value varchar(20) = (select top 1 ref from #t1)
insert into #t2 select * from table2 where ref = #ref
delete from #t1
where ref = #value
set #len = (select count(ref) from #t1)
end
select * from #t2
Java code
....
String query = "Execute [p2]";
try(CallableStatement cstmt = conn.prepareCall(query);
ResultSet rs = cstmt.executeQuery()){
... some code
}
The table variable #t1 hold select result from a table 'table1'
The variable #len hold the number of rows in #t1
Using #len > 0 as condition in while loop, I want to select records from another table 'table2' the table variable #t2 hold the select records from 'table2'
The delete statement removes value from #t1
#len set to new number of rows in #t1
the last statement return all the records store in #t2
The first procedure works fine, but the second procedure works only in SQL Server.
I get this an error message in my java application
statement did not return a resultset
I want this to return a result set with the select statement I have at the
end of the query.
Please is there a way around this?
Your [p2] stored procedure needs to include SET NOCOUNT ON right at the beginning to suppress the "n rows affected" counts so JDBC doesn't get confused as to what it should put into the ResultSet:
CREATE PROCEDURE p2
AS
SET NOCOUNT ON;
declare #t1 table(
ref varchar(20)
)
-- ... and so on
For more information on SET NOCOUNT see
SET NOCOUNT (Transact-SQL)
For more information on precisely what gets returned from a stored procedure call, see
How to get everything back from a stored procedure using JDBC
use method "execute" instead of "executeQuery".

how to pass multiple values in single parameter and how to convert varchar value into integers

CREATE TABLE students
( id INT,
NAME varchar(20)
)
INSERT INTO students(id,name)VALUES(1,'Danny')
INSERT INTO students(id,name)VALUES(2,'Dave')
INSERT INTO students(id,name)VALUES(3,'Sue')
INSERT INTO students(id,name)VALUES(4,'Jack')
INSERT INTO students(id,name)VALUES(5,'Rita')
INSERT INTO students(id,name)VALUES(6,'Sarah')
This is my stored procedure
alter PROCEDURE emp_sp
(
#std_id as VARCHAR(500),
#std_name as varchar(500)
)
AS
begin
SELECT *FROM Students s
WHERE s.id IN(convert(INT,#std_id) ,',')
AND
s.NAME IN(#std_name)
END
GO
Here I execute it manually
EXEC dbo.emp_sp #std_id='1,2,3', #std_name='"Danny","Dave","Sue"'
but I get this error:
Msg 245, Level 16, State 1, Procedure emp_sp, Line 8
Conversion failed when converting the varchar value ',' to data type int.
Anyone can guide me.
To get your current approach working, you will need to use Dynamic Sql, which will be incredibly fragile and prone to Sql Injection attacks. Example of this Here
The better way to do this is through Table Valued Parameters:
CREATE TYPE ttStudentIDs AS TABLE
(
ID INT
);
GO
CREATE TYPE ttStudentNames AS TABLE
(
Name VARCHAR(20)
);
GO
CREATE PROCEDURE dbo.emp_sp
(
#stdIds ttStudentIDs READONLY,
#stdNames ttStudentNames READONLY
)
AS
begin
SELECT s.ID, s.Name
FROM Students s
INNER JOIN #stdIds si
ON s.ID = si.ID
UNION
SELECT s.ID, s.Name
FROM Students s
INNER JOIN #stdNames sn
ON s.Name = sn.Name;
END
GO
And called like so:
DECLARE #Ids AS ttStudentIDs;
DECLARE #Names AS ttStudentNames;
INSERT INTO #Ids VALUES (1),(2),(3);
INSERT INTO #Names VALUES ('Danny'),('Dave'),('Sue');
EXEC dbo.emp_sp #Ids, #Names;
SqlFiddle here

Resources