Is is possible to create a stored procedure using cfstoredproc? When I run the following I get Incorrect syntax near 'GO'.
<cffile action="read" file="mypath/myFile.sql" variable="sp_1">
<cfstoredproc procedure="sp_executesql" dataSource="#getDatasource()#">
<cfprocparam type="in" cfsqltype = "cf_sql_varchar" value ='#sp_1#'>
</cfstoredproc>
myFile.sql
IF OBJECT_ID('getMyData', 'P') IS NOT NULL
DROP PROC getMyData
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE getMyData
#some_var AS NVARCHAR(200)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sql AS NVARCHAR(MAX)
SET #sql = N'SELECT * FROM myTable where id = ''' + #some_var + ''' '
EXEC sp_executeSQL #sql
END
<cfquery name="createGetMyData" dataSource="#getDatasource()#">
#preservesinglequotes(sp_1)#
</cfquery>
Try this:
<cffile action="read" file="mypath/myFile.sql" variable="sp_1">
<cfstoredproc procedure="sp_executesql" dataSource="#getDatasource()#">
<cfprocparam type="in" cfsqltype = "cf_sql_varchar" value ='#preservesinglequotes(sp_1)#'>
</cfstoredproc>
ColdFusion escapes your single quotes in db variables.
EDIT:
Secondly there is the batching of statements. the drive will batch your query as a single statement wheras the "GO" keyword is an indicator of a batch prepared. In other words, your "GO" actually IS the issue.
To fix it you will need to run 2 querys - one to drop and the other to create. Why? Because CREATE PROCEDURE actually has to be the first statement in a given batch. in MSSQL studio, using GO, you are creating 3 batches, now you have to figure out how to use one.
The good news is that your ANSI nulls and Quoted identifiers are probably not needed - they are defaulted on most instances.
Does this help?
Related
I need to write a procedure in Redshift that will write to a table, but the table name comes from the input string. Then I declare a variable that puts together the table name.
CREATE OR REPLACE PROCEDURE my_schema.data_test(current "varchar")
LANGUAGE plpgsql
AS $$
declare new_table varchar(50) = 'new_tab' || '_' || current;
BEGIN
select 'somestring' as colname into new_table;
commit;
END;
$$
This code runs but it doesn't create a new table, no errors. If I remove the declare statement then it works, creating a table called "new_table". It's just not using the declared variable name.
It's hard to find good examples because Redshift is postgresql and all the postgresql pages say that it only has functions, not procedures. But Redshift procedures were introduced last year and I don't see many examples.
Well, when you are declaring a variable "new_table", and performing a SELECT ..INTO "new_table", the value is getting assigned to the variable "new_table". You will see that if you return your variable using a OUT parameter.
And when you remove the declaration, it simply work as a SELECT INTO syntax of Redshift SQL and creates a table.
Now to the solution:
Create a table using the CREATE TABLE AS...syntax.
Also you need to pass the value of declared variable, so use the EXECUTE command.
CREATE OR REPLACE PROCEDURE public.ct_tab (vname varchar)
AS $$
DECLARE tname VARCHAR(50):='public.swap_'||vname;
BEGIN
execute 'create table ' || tname || ' as select ''name''';
END;
$$ LANGUAGE plpgsql
;
Now if you call the procedure passing 'abc', a table named "swap_abc" will be created in public schema.
call public.ct_tab('abc');
Let me know if it helps :)
I have a stored procedure in Informix that uses external tables to unload data to a disk file from a select statement. Is it possible to give the DISK file name as a parameter to the stored procedure? My stored procedure is as follows:
create procedure spUnloadData(file_name_param varchar(64))
create temp table temp_1(
col_11 smallint
) with no log;
INSERT INTO temp_1 select col1 from data_table;
CREATE EXTERNAL TABLE temp1_ext
SAMEAS temp_1
USING (
--DATAFILES ("DISK:/home/informix/temp.dat")
DATAFILES("DISK:" || file_name_param )
);
INSERT INTO temp1_ext SELECT * FROM temp_1;
DROP TABLE temp1_ext ;
DROP TABLE temp_1;
END PROCEDURE;
I am trying to pass in the DISK filename as a parameter(from my shell script, timestamped).
Any help is appreciated.
NH
You would have to use Dynamic SQL in the stored procedure — for example, the EXECUTE IMMEDIATE statement.
You create a string containing the text of the SQL and then execute it. Adapting your code:
CREATE PROCEDURE spUnloadData(file_name_param VARCHAR(64))
DEFINE stmt VARCHAR(255); -- LVARCHAR might be safer
CREATE TEMP TABLE temp_1(
col_11 SMALLINT
) WITH NO LOG;
INSERT INTO temp_1 select col1 from data_table;
LET stmt = 'CREATE EXTERNAL TABLE temp1_ext ' ||
'SAMEAS temp_1 USING DATAFILES("DISK:' ||
TRIM(file_name_param) ||
'")';
EXECUTE IMMEDIATE stmt;
INSERT INTO temp1_ext SELECT * FROM temp_1;
DROP TABLE temp1_ext;
DROP TABLE temp_1;
END PROCEDURE;
Untested code — the concept should be sound, though.
This assumes you are using a reasonably current version of Informix; the necessary feature is in 12.10, and some version 11.70 versions too, I believe.
I made slight changes to my code to unload data(as Informix default '|' separated fields). Instead of using a temp table, I was able to select columns directly into an external table dynamically.
I'm trying to define a DB2 Stored Proc that would (ideally), CREATE VIEW, then do a SELECT against that VIEW to build another piece of SQL, then execute that SQL using a CURSOR and return a result set.
I've 2 problems:
DB2 doesn't appear to like the mix of CREATE, SELECT and DECLARE CURSOR within a single SP,
and I can't figure out what syntax to use to declare a cursor based on SQL that is stored as a string in the declared VARCHAR that is the output from the SELECT statement.
Has anyone done anything similar and/or able to give me some syntax examples?
Sure you can do that in DB2. In order to execute a 'create view' you need to use a dynamic SQL. The same for the select on the view. Finally, for the cursor, you define a generic cursor, and execute it dynamically.
DECLARE SENTENCE VARCHAR(256);
DECLARE TABNAME VARCHAR(128);
DECLARE STMT STATEMENT;
DECLARE TABLES_CURSOR CURSOR
FOR TABLES_RS;
SET SENTENCE = 'CREATE VIEW TABS SELECT TABNAME FROM SYSCAT.TABLES';
PREPARE STMT FROM SENTENCE;
EXECUTE STMT;
SET SENTENCE = 'SELECT TABNAME FROM TABS';
PREPARE TABLES_RS FROM SENTENCE;
OPEN TABLES_CURSOR;
FETCH TABLES_CURSOR INTO TABNAME;
You can see real SQL PL examples in my project db2unit https://github.com/angoca/db2unit/blob/master/src/main/sql-pl/04-Body.sql
I need to modify a stored procedure that will update a price table on a live database.
I am using MS SQL Server 2005, and the stored procedure is used as a query in SAP BI.
I have this part:
SET #cmd ='Update PriceList 5'
SET #sql ='UPDATE a SET a.price= round( (b.price*0.9),0), a.currency=b.currency FROM ['+#trgDB+'].[dbo].[ITM1] a '
SET #sql =#sql+' INNER JOIN ['+#trgDB+'].[dbo].[ITM1] b ON ( a.ItemCode=b.itemcode AND b.PriceList=1) '
SET #sql =#sql+' WHERE a.PriceList=5 '
IF #filter IS NOT NULL BEGIN
SET #sql =#sql+' AND a.[ItemCode] LIKE '+char(39)+#filter+'%'+char(39)+' '
SET #cmd = #cmd+' ('+#filter+'%'+') '
END
This will update the price on every item acording to filter.
I need to leave some items unchanged, so how can I add NOT LIKE 'VSK%' AND NOT LIKE 'VFH%' to the code above? It doesn't matter if the flter is left out, but then I need every price to be updated except NOT LIKE 'VSK%' AND NOT LIKE 'VFH%' .
table http://qupload.com/images/clipbosjs.jpg
Techies--
I'm getting sql0204 XML in *LIBL type *SQLUDT not found on an i db2 6.1 install when I try to deploy a stored proc I know works on Linux v9.7. The reason I am attempting to get this to work is because I really need to pass a table (or array) variable. I couldn't find a way to send a multi-dim array to a sproc on the 6.1 v of i, so I thought I'd try getting around that with an xml doc. But that failed too... Does anyone have any advice for me on how to solve this issue?
Here's the sproc that works on v9.7,Linux:
CREATE PROCEDURE HCMDEV.EMP_MULTIPLE_XML (IN DOC XML)
DYNAMIC RESULT SETS 1
READS SQL DATA
LANGUAGE SQL SPECIFIC EMP_MULTIPLE_XML
P1: BEGIN
DECLARE CSR1 CURSOR WITH RETURN FOR
SELECT emp.EMPID,
emp.FIRSTNAME,
emp.LASTNAME,
emp.DIVISION,
emp.DISTRICT,
emp.LOCATION,
emp.OPERATIONALAREA,
emp.TERMDATE,
emp.REHIREDATE,
emp.HIREDATE,
emp.ADDRESSLINE1,
emp.ADDRESSLINE2,
emp.CITY,
emp.STATE,
emp.ZIPCODE,
emp.TELEPHONE1,
emp.POSITIONCODE,
emp.POSITIONTITLE,
emp.HIRECODE
FROM HCMDEV.EMPLOYEE emp
WHERE EMP.EMPID IN
(SELECT X.EMPID
FROM XMLTABLE('$d/EMPLOYEE/EMPID' PASSING DOC AS "d" COLUMNS EMPID CHAR(9) PATH '.') AS X);
OPEN CSR1;
END P1
For those following this thread, xmltable is NOT available until V7R1. The workaround is to create a stored proc that accepts as the IN paramater a CLOB datatype. In my case, I pass a long string with commas to separate the values for the empid. That works just fine.
Here's a sampling:
CREATE PROCEDURE HCMDEV.EMP_MULT (IN emp_array CLOB(2M))
DYNAMIC RESULT SETS 1
READS SQL DATA
LANGUAGE SQL SPECIFIC EMP_MULT
P1: BEGIN
-- #######################################################################
-- # Returns specific employees based on incoming clob array
-- #######################################################################
DECLARE v_dyn varchar(10000);
DECLARE v_sql varchar(10000);
DECLARE cursor1 CURSOR WITH RETURN FOR v_dyn;
SET v_sql =
'SELECT
emp.EMPID,
emp.FIRSTNAME,
emp.LASTNAME
FROM HCMDEV.EMPLOYEE emp
WHERE emp.EMPID IN (' || emp_array || ')';
PREPARE v_dyn FROM v_sql;
OPEN cursor1;
END P1