Pass comma separated number to IN clause in Stored Procedure - stored-procedures

I have a stored procedure which takes a varchar parameter called P_LOCATIONS in Oracle. This locations parameter has location id's that are comma separated. In database locationId is a number.
Following sql query throws an Invalid number when there are more than one locations. I understand that because of comma its not able to convert a varchar into a number. How can I achieve this?
create or replace PROCEDURE GET_RAW_DATA
( P_LOCATIONS IN VARCHAR2,
Results OUT SYS_REFCURSOR
)AS
BEGIN
select * from tableName where LOCATION_ID IN ( P_LOCATIONS);
END GET_RAW_DATA;

The end result of what you are doing is this:
select * from tableName where LOCATION_ID IN ('1,2,3');
And what you need is this:
select * from tableName where LOCATION_ID IN (1,2,3);
So you can use this:
select * from tableName where LOCATION_ID in (
select regexp_substr(P_LOCATIONS,'[^,]+{1}',1,level)
from dual connect by level <= length(regexp_replace(P_LOCATIONS,'[^,]*')) + 1
);

Related

how to stored procedures with bigquery?

I want to replace text and column name by stored procedures and it didn't change the value.
CREATE OR REPLACE PROCEDURE dataset.test_pivot(name STRING)
BEGIN
SELECT 'name',* FROM
(
SELECT
name
FROM `dataset.mytable`
)
PIVOT
(
count(*) AS N
FOR name in ('P1', 'P2', 'P3', 'P4', 'P5', 'P6', 'P7', 'P8', 'P9', 'P10')
);
END
CALL dataset.test_pivot(inte_acedemic);
The result is
https://i.stack.imgur.com/u6PKm.png
I want replace name with inte_acedemic. Many thanks!

Solve the syntax error with Redshift operator does not exist and add explicit casts

I am a newbie in the area of redshift data modeling and got myself into trouble with an error.ERROR:
--Final version
syntax error ERROR: operator does not exist: text | record Hint: No
operator matches the given name and argument type(s). You may need to
add explicit type casts. Where: SQL statement "SELECT 'create temp
table ' || $1 || ' as select * from' | $2 |" PL/pgSQL function "egen"
line 36 at execute statement [ErrorId:
1-61dc32bf-0a451f5e2c2639235abb8876]
I am trying to do a simple transformation that gets returned in output when the procedure is called. (As of now I got to find from the documentation we have to use either temp table or cursors to achieve this)
Pseudocode:
I am trying to restrict data to its latest one in (2019) Get the
list of managers create columns if a person is a manager or not from the list.
Return it as a result
Data looks as follows Employee Data
My Select query works fine out of the procedure, please find my complete code below.
CREATE OR REPLACE PROCEDURE EGEN(tmp_name INOUT varchar(256) )
AS $$
DECLARE
--As i have less data managed to create it as an array or please use temp or table and join it with the actual query to perform transformation
MGR_RECORD RECORD;
DATAS RECORD;
item_cnt int := 0;
V_DATE_YEAR int := 0;
BEGIN
--EXECUTE (select cast(extract(year from current_date) as integer)-3) INTO V_DATE_YEAR;
--Manager Records are stored here below
SELECT DISTINCT managerid from "dev"."public"."emp_salary" INTO MGR_RECORD;
SELECT employeeid,
managerid,
promotion,
q_bonus,
d_salary,
case when contractor = 'x'
then 'TemporaryEmployee'
else 'PermanentEmployee'
END as EmployeeType,
-- IFstatement not supported under select query
case when employeeid in (select distinct managerid FROM "dev"."public"."emp_salary" )
then 'Manager'
else 'Ordinary FTE'
END as FTETYPE
FROM "dev"."public"."emp_salary" where cast(extract(year from promotion) as int ) >= 2019 into DATAS;
--COMMIT;
tmp_name := 'ManagerUpdatedTable';
EXECUTE 'drop table if exists ' || tmp_name;
EXECUTE 'create temp table ' || 'ManagerUpdatedTable' || ' as select * from' |DATAS| ;
END;
$$ LANGUAGE plpgsql;
-- Call tests CALL EGEN('myresult'); SELECT * from myresult;
Also, additional query (Can we replace )
case when employeeid in (select distinct managerid FROM "dev"."public"."emp_salary" )
then 'Manager'
else 'Ordinary FTE'
END as FTETYPE
this transform in query to IF , if possible please provide details.
Thanks and Regards,
Gabby

I have a stored procedure which returns Dynamic columns(using Pivot) I want to bind stored procedure with RDLC report

I want to create RDLC report ,but the problem is that Columns in a table returned by the stored procedure are Dynamic, means Columns can be increased or decrease depends on the condition.
I have Created procedure.
alter proc sp_GetEmpBranAndDesigWise(
#BranchId nvarchar(200),
#ZoneId nvarchar(200)
)
as
if 1=0 Begin
set FMTONLY OFF End
select b.BranchName,b.BranchCity,z.ZoneName,b.BranchID,d.DesigName
,Count(d.DesigName) as TotalCount
INTO #RepTablTemp
from Emp_File emp
INNER join Branch b on emp.BranchID=b.BranchID
left join ZoneFile z on z.ZoneID=b.ZoneID
INNER join SWHouse_Production.dbo.emp_DesigFile d on emp.DesigID=d.DesigID
where Convert(nvarchar(250), b.BranchID) like #BranchId
and Convert(nvarchar(250), b.ZoneID) like #ZoneId
group by b.BranchName,z.ZoneName,b.BranchCity,b.BranchID,d.DesigName
order by b.BranchName,z.ZoneName,d.DesigName
--select * from #RepTablTemp order by BranchName,DesigName
--select * from Emp_File where BranchID=1055
Begin
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(DesigName)
from #RepTablTemp
group by DesigName
--order by 1
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
print #cols
set #query = N'SELECT BranchName,ZoneName,BranchCity,' + ISNULL(#cols,'0') + N' from
(
select BranchName,ZoneName,BranchCity,TotalCount, DesigName
from #RepTablTemp
) x
pivot
(
max(TotalCount)
for DesigName in (' + #cols + N')
) p '
exec sp_executesql #query;
select 0 AS mycol1int
print #query
drop table #RepTablTemp
End
BranchName|ZoneName|BranchCity|Designation1|Designation2|Designation3
here Designations are dynamic and can be increased,i want this kind of result in RDLC
enter image description here
In attached file highlighted fields are Designations coming from Designation Table.
You can't do that. RDLC expects a fixed "object" for a table. You can pass a dynamic object, but this object must be match with the dataset provided to the table.
But you can use several tablix and show them or not (visibility condition) for an specific condition loaded by a parameter (for example, a kind of table do you want to see or hide).

Conversion failed when converting the varchar value '1,2' to data type int

When I pass more than one id in sql server stored procedure it throws error like this==> Conversion failed when converting the varchar value '1,2' to data type int.
and this is the sql query
===>SELECT * FROM SomeTAble WHERE colName in(#Ids)
If your stored procedure parameter expecting varchar(n), please have a look at accepted answer from T-SQL split string to split the value from a varchar.
Then you can apply the function in your stored procedure, you can simply change the query to something like this:
alter procedure your_stored_procedure
#ids varchar(50)
as
begin
select *
from some_table
where colName in (splitstring(#ids))
end
go
However, if your stored procedure accepting int as parameter, please change it to varchar or any data type. Your stored procedure won't work because int will only accept single integer value.
You have to split string into rows first.
for do that you can use my sql Splitext function
Here is Installing Script
DROP FUNCTION IF EXISTS [dbo].[SplitText]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[SplitText]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
BEGIN
execute dbo.sp_executesql #statement = N'CREATE FUNCTION [dbo].[SplitText]
( #TextForSplit varchar(1000)
, #SplitWith varchar(5) = '',''
)
RETURNS #DataSource TABLE
(
ID TINYINT identity,
[Value] VARCHAR(500) NOT NULL
)
AS
BEGIN
DECLARE #XML xml = N''<r><![CDATA['' + REPLACE(#TextForSplit, #SplitWith, '']]></r><r><![CDATA['') + '']]></r>''
INSERT INTO #DataSource ([Value])
SELECT RTRIM(LTRIM(T.c.value(''.'', ''NVARCHAR(128)'')))
FROM #xml.nodes(''//r'') T(c)
DELETE #DataSource WHERE [VALUE] = ''''
RETURN
END
END
GO
And this is how to use it.
SELECT * FROM SomeTAble WHERE colName in( select value from Splittext('1,2,3,4,5' , ','))

How to use procedure parameters in merge statement

i'm creating a procedure to update/insert a table using merge statement(upsert).now i have a problem: using procedure parameters i have to do this upsert.
procedure xyz( a in table.a%type,b in table.b%type,....)
is
some local variables;
begin
merge into target_table
using source_table --instead of the source table, i have to use procedure parameters here
on (condition on primary key in the table)
when matched then
update the table
when not matched then
insert the table ;
end xyz;
so how to use procedure parameters instead of source table in merge statement?? or
suggest me a query to fetch the procedure parameters and use it as source table values.
help me please.
Thanks in advance.
I know that I'm eight years late to the party, but I think that I was trying to do something similar to what you were doing, but trying to Upsert based on parameters passed into a stored procedure that returns an empty string on success and an error on failure back to my VB Code. Below is all of my code along with comments explaining what I did, and why I did it. Let me know if this helps you or anyone else. This is my first time answering a post.
PROCEDURE UpsertTSJobData(ActivitySeq_in IN NUMBER,
Owner_in In VARCHAR2,
NumTrailers_in IN NUMBER,
ReleaseFormReceived_in IN NUMBER,
Response_out OUT VARCHAR2) AS
err_num NUMBER;
err_msg VARCHAR2(4000);
BEGIN
--This top line essentially does a "SELECT *" from the named table
--and looks for a match based on the "ON" statement below
MERGE INTO glob1app.GFS_TS_JOBDATA_TAB tsj
--This select statement is used for the INSERT when no match
--is found and the UPDATE when a match is found.
--It creates a "pseudo-table"
USING (
SELECT ActivitySeq_in AS ActSeq,
Owner_in As Owner,
NumTrailers_in As NumTrailers,
ReleaseFormReceived_in As ReleaseFormReceived
FROM DUAL) input
--This ON statement is what we're doing the match on to find
--matching records. This decides whether it will be an
--INSERT or an UPDATE
ON (tsj.Activity_seq = ActivitySeq_in)
WHEN MATCHED THEN
--Here we UPDATE based on the passed in input table
UPDATE
SET OWNER = input.owner,
NUMTRAILERS = input.NumTrailers,
RELEASEFORMRECEIVED = input.releaseformreceived
WHEN NOT MATCHED THEN
--Here we INSERT based on the passed in input table
INSERT (
ACTIVITY_SEQ,
OWNER,
NUMTRAILERS,
RELEASEFORMRECEIVED
)
VALUES (
input.actseq,
input.owner,
input.numtrailers,
input.releaseformreceived
);
Response_out := '';
EXCEPTION
WHEN OTHERS THEN
err_num := SQLCODE;
err_msg := SUBSTR(SQLERRM, 1, 3900);
Response_out := TO_CHAR (err_num) || ': ' || err_msg;
END;
Maby something like
DECLARE V_EXISTS NUMBER;
BEGIN SELECT COUNT(*) INTO V_EXISTS FROM TARGET_TABLE WHERE PK_ID = :ID;
IF V_EXISTS > 0 THEN
-- UPDATE
ELSE
-- INSERT
END IF;
END;
Also, you may try to use so-called tempotary table (select from DUAL)
CREATE TABLE TEST (N NUMBER(2), NAME VARCHAR2(20), ADRESS VARCHAR2(100));
INSERT INTO TEST VALUES(1, 'Name1', 'Adress1');
INSERT INTO TEST VALUES(2, 'Name2', 'Adress2');
INSERT INTO TEST VALUES(3, 'Name3', 'Adress3');
SELECT * FROM TEST;
-- test update
MERGE INTO TEST trg
USING (SELECT 1 AS N, 'NameUpdated' AS NAME,
'AdressUpdated' AS ADRESS FROM Dual ) src
ON ( src.N = trg.N )
WHEN MATCHED THEN
UPDATE
SET trg.NAME = src.NAME,
trg.ADRESS = src.ADRESS
WHEN NOT MATCHED THEN
INSERT VALUES (src.N, src.NAME, src.ADRESS);
SELECT * FROM TEST;
-- test insert
MERGE INTO TEST trg
USING (SELECT 34 AS N, 'NameInserted' AS NAME,
'AdressInserted' AS ADRESS FROM Dual ) src
ON ( src.N = trg.N )
WHEN MATCHED THEN
UPDATE
SET trg.NAME = src.NAME,
trg.ADRESS = src.ADRESS
WHEN NOT MATCHED THEN
INSERT VALUES (src.N, src.NAME, src.ADRESS);
SELECT * FROM TEST;
DROP TABLE TEST;
see here
Its very difficult to tell from you question exactly what you what, but I gather you want the table that you are merging into ( or on ) to be dynamic. In that case, what you should be using is the DBMS_SQL package to create dynamic SQL

Resources