Is it possible to store the results of a call to exec sp_executesql in a 'table parameter'. The parameter value is used in another SQL Stored procedure (SQL 2000/2005)
Best you can do is insert the values into a temp table (using an INSERT EXEC pattern) and then use that temp table in the second proc down the chain ...
If you are wanting to store the results of some process in a table variable, I would suggest making it a table-value function instead of a sproc. That way you can then use the end-result of the first function in whatever other processing you are doing
Select * from MyTableValueFunction()
Related
I want to write a stored procedure in DB2 database for UPDATE and DELETE operations.
I am able to do that by directly providing values in procedure, but I want to do it by passing dynamic values.
My Table Structure is -
create table emp2 (int_1 int, char_1 char(10))
Below is my stored procedure for UPDATE operation which I am able to run but, its not behaving as per expectations. Changes are not reflecting in DB even after passing correct parameters while calling stored procedure.
CREATE OR REPLACE PROCEDURE "DB2INST1"."UPDATE_1" (IN int_1 int, IN
char_1 char(10)) SPECIFIC UPDATE_1
LANGUAGE SQL
DYNAMIC RESULT SETS 1
BEGIN
update emp2 set char_1=char_1 where int_1=int_1;
END;
This is the my stored procedure for DELETE operation which I am able to run successfully, but it's deleting all rows from the database table instead of deleting a single row:
CREATE OR REPLACE PROCEDURE "DB2INST1"."DELETE_1" (IN int_1 int)
SPECIFIC DELETE_1
LANGUAGE SQL
DYNAMIC RESULT SETS 1
BEGIN
delete from emp2 where int_1=int_1;
END;
Please provide me syntax for creating stored procedure for UPDATE and DELETE operations by passing dynamic values in a DB2 database.
The problem is that you don't qualify your columns and parameters having the same names.
According to the References to SQL parameters, SQL variables, and global variables:
Names that are the same should be explicitly qualified. Qualifying a
name clearly indicates whether the name refers to a column, SQL
variable, SQL parameter, row variable field, or global variable. If
the name is not qualified, or qualified but still ambiguous, the
following rules describe whether the name refers to a column, an SQL
variable, an SQL parameter, or a global variable:
If the tables and views specified in an SQL routine body exist at the time the routine is created, the name is first checked as a column
name. If not found as a column, it is then checked as an SQL variable
in the compound statement, then checked as an SQL parameter, and then,
finally, checked as a global variable.
That is, the following statements changing all the table rows obviously are equivalent:
update emp2 set char_1 = char_1 where int_1 = int_1;
--and
update emp2 e set e.char_1 = e.char_1 where e.int_1 = e.int_1;
What you need is to rewrite this statement to the following, if you want to use the same column and parameter names (the routine name UPDATE_1 is used here for the parameter qualification).
update emp2 set char_1 = UPDATE_1.char_1 where int_1 = UPDATE_1.int_1
fiddle
Consider an enterprise that captures sensor data for different production facilities. per facility, we create an aggregation query that averages the values to 5min timeslots. This query exists out of a long list of with-clauses and writes data to a table (called aggregation_table).
Now my problem: currently we have n queries running that exactly run the same logic, the only thing that differs are table names (and sometimes column names but let's ignore that for now).
Instead of managing n different scripts that are basically the same, I would like to put it in a stored procedure that is able to work like this:
CALL aggregation_query(facility_name) -> resolve the different tables for that facility and then use them in the different with clauses
On top of that, instead of having this long set of clauses that give me the end-result, I would like to chunk them up in logical blocks that are parametrizable, So for example, if I call the aforementioned stored_procedure for facility A, I want to be able to pass / use this table name in these different functions, where the output can be re-used in the next statement (like you would do with with clauses).
Another argument of why I want to chunk this up in re-usable blocks is because we have many "derivatives" on this aggregation query, for example to manage historical data, to correct data or to have the sensor data on another aggregation level. As these become overly complex, it is much easier to manage them without having to copy paste and adjust these every time.
In the current set-up, it could be useful to know that I am only entitled to use plain BigQuery, As my team is not allowed to access the CI/CD / scheduling and repository. (meaning that I cannot solve the issue by having CI/CD that deploys the n different versions of the procedure and functions)
So in the end, I would like to end up with something like this using only bigquery:
CREATE OR REPLACE PROCEDURE
`aggregation_function`()
BEGIN
DECLARE
tablename STRING;
DECLARE
active_table_name STRING; ##get list OF tables CREATE TEMP TABLE tableNames AS
SELECT
table_catalog,
table_schema,
table_name
FROM
`catalog.schema.INFORMATION_SCHEMA.TABLES`
WHERE
table_name = tablename;
WHILE
(
SELECT
COUNT(*)
FROM
tableNames) >= 1 DO ##build dataset + TABLE name
SET
active_table_name = CONCAT('`',table_catalog,'.',table_schema,'.' ,table_name,'`'); ##use concat TO build string AND execute
EXECUTE IMMEDIATE '''
INSERT INTO
`aggregation_table_for_facility` (timeslot, sensor_name, AVG_VALUE )
WITH
STEP_1 AS (
SELECT
*
FROM
my_table_function_step_1(active_table_name,
parameter1,
parameter2) ),
STEP_2 AS (
SELECT
*
FROM
my_table_function_step_2(STEP_1,
parameter1,
parameter2) )
SELECT * FROM STEP_2
'''
USING active_table_name as active_table_name;
DELETE
FROM
tableNames
WHERE
table_name = tablename;
END WHILE
;
END
;
I was hoping someone could make a snippet on how I can do this in Standard SQL / Bigquery, so basically:
stored procedure that takes in a string variable and is able to use that as a table (partly solved in the approach above, but not sure if there are better ways)
(table) function that is able to take this table_name parameter as well and return back a table that can be used in the next with clause (or alternatively writes to a temp table)
I think below code snippets should provide you with some insights when dealing with procedures, inserts and execute immediate statements.
Here I'm creating a procedure which will insert values into a table that exists on the information schema. Also, as a value I want to return I use OUT active_table_name to return the value I assigned inside the procedure.
CREATE OR REPLACE PROCEDURE `project-id.dataset`.custom_function(tablename STRING,OUT active_table_name STRING)
BEGIN
DECLARE query STRING;
SET active_table_name= (SELECT CONCAT('`',table_catalog,'.',table_schema,'.' ,table_name,'`')
FROM `project-id.dataset.INFORMATION_SCHEMA.TABLES`
WHERE table_name = tablename);
#multine query can be handled by using ''' or """
Set query =
'''
insert into %s (string_field_0,string_field_1,string_field_2,string_field_3,string_field_4,int64_field_5)
with custom_query as (
select string_field_0,string_field_2,'169 BestCity',string_field_3,string_field_4,55677 from %s limit 1
)
select * from custom_query;
''';
# querys must perform operations and must be the last thing to perform
# pass parameters using format
execute immediate (format(query,active_table_name,active_table_name));
END
You can also use a loop to iterate trough records from a working table so it will execute the procedure and also be able to get the value from the procedure to use somewhere else.ie:A second procedure to perform a delete operation.
DECLARE tablename STRING;
DECLARE out_value STRING;
FOR record IN
(SELECT tablename from `my-project-id.dataset.table`)
DO
SET tablename = record.tablename;
LOOP
call `project-id.dataset`.custom_function(tablename,out_value);
select out_value;
END LOOP;
END FOR;
To recap, there are some restrictions such as the possibility to call procedures inside a execute immediate or to use execute immediate inside an execute immediate, to count a few. I think these snippets should help you dealing with your current situation.
For this sample I use the following documentation:
Data Manipulation Language
Dealing with outputs
Information Schema Tables
Execute Immediate
For...In
Loops
I want to retrieve data in Delphi using a stored procedure. I used the below SQL statement and Initial as a parameter:
SELECT * FROM "PackUser" where Initials in (:Initial)
It didn't select any records when the user types A,B in my Edit box, because it sends a single string 'A,B' to the stored procedure. I want to add extra quotes in the middle: 'A','B'.
How can I do this?
This can be done like this:
input_string=',A,B,C.D'
SELECT * FROM "PackUser" where locate(concat(',', Initials), input_string);
I'm calling a Sybase Stored Proc X that returns data that is used by a servlet.
Within Stored Proc X, Stored Proc get_business_day is called in the following manner:
exec get_business_day #CBDate, -1, #prevBusDay output
So, the result of calling this (in DBArtisan) is:
6/25/2010 12:00:00.000 AM
1 row(s) affected.
The issue is that I do not need this above row to be outputted when executing X, as the output I get (in DBArtisan) is:
6/25/2010 12:00:00.000 AM
-2817773441.669999
This will obviously affect the results obtained by the servlet as it expects only the value -2817773441.669999.
Is there any way to suppress the output of get_business_day appearing when calling X?
Thx
Agnyata
here is the what you want to do:
main proc:
...
create table #tmp(
CBDate datetime
)
EXEC get_business_day #CBDate, -1
select CBDate from #tmp
-- use it
drop table #tmp
-- before end
get_business_day:
create table #tmp(
CBDate datetime
)
go
create proc get_business_day
as
-- find the value to be inserted into #day
insert into #tmp select #day
go
drop table #tmp
go
try capturing the result set in a temp table, something like this:
CREATE TABLE #BadResultSet (DateOf datetime)
INSERT INTO #BadResultSet (DateOf)
EXEC get_business_day #CBDate, -1, #prevBusDay output
Is it possitble to get a stored-procedure's result set as a table so that I can query that?
something like:
SELECT PK_Item, Count(PK_Item)
FROM (pMyStoredProcedure) --This sp returns a table that has PK_Item column
GROUP BY PK_ITEM
ORDER BY PK_ITEM DESC
I am not an T-SQL expert but my friend says it is kind of impossible to do this with sprocs.
Is not there any way? But without modifying the stored procedure.
thanks!
If you know the table structure that the sp will return using sql server 2005
you can use
declare #table table(
columns here...
)
INSERT INTO #table exec your_sp params
select * from #table