I got a error message in my procedure like
(-3706) Syntax error: something was expected between the word 'DBO' and '.'.
I don't understand why?
This is my code:
CREATE PROCEDURE [dbo].[PS_DIM_FILMS]
AS
BEGIN
INSERT INTO FILMS.DBO.[T_DIM_FILMS]
SELECT *
FROM OPENQUERY(linked_server,
'SELECT
REG.CODE_FILMS, REG.NAME_FILMS,
DEP.CODE_SERIES, DEP.NAME_SERIES
FROM SERV.DBO.T_FILMS REG
INNER JOIN SERV.DBO.T_EXCEL_SERIES DEP
ON DEP.CODE_SERIES = REG.CODE_FILMS')
END
Related
I have created following stored procedure to update recon_dashboard table.
create or replace procedure ca_adhoc_view.sp_count_recon_refresh()
language plpgsql as
$$
declare
f record;
BEGIN
for f in select alvid from ca_adhoc_view.recon_dashboard
loop
raise notice '% alv',f.alv;
execute 'update ca_adhoc_view.recon_dashboard set alv_count =
(select count(*) from ' || f.alv || ')
where id='|| f.id;
end loop;
END;
$$;
It works fine unless there is a null value in the alv, then it throws an error.
I tried to check for null like:
create or replace procedure ca_adhoc_view.sp_count_recon_refresh()
language plpgsql as
$$
declare
f record;
BEGIN
for f in select alv,id from ca_adhoc_view.recon_dashboard
loop
raise notice '% alv',f.alv;
execute 'update ca_adhoc_view.recon_dashboard set alv_count =
(IF '||f.alv||' is not null
then (select count(*) from ' || f.alv || ')
END IF;)
where id='|| f.id;
end loop;
END;
$$;
But it throws error when I try to call the SP.
Error: SQL Error [42601]: ERROR: syntax error at or near "ca_view"
Where: PL/pgSQL function "sp_count_recon_refresh" line 7 at execute statement
In error "ca_view" is a recod. alv column has values like 'ca_view.table1', 'ca_view.table2' and so on.
This probably fixes your problems:
CREATE OR REPLACE PROCEDURE ca_adhoc_view.sp_count_recon_refresh()
LANGUAGE plpgsql AS
$func$
DECLARE
f record;
BEGIN
FOR f IN
SELECT alv, id FROM ca_adhoc_view.recon_dashboard
LOOP
RAISE NOTICE '% alv', f.alv;
IF f.alv IS NOT NULL THEN
EXECUTE format(
'UPDATE ca_adhoc_view.recon_dashboard
SET alv_count = (SELECT count(*) FROM %I)
WHERE id = $1', f.alv)
USING f.id;
END IF;
END LOOP;
END
$func$;
"Problems" (plural). Besides defending against a NULL value for the table name with proper syntax, this also prevents SQL injection. Your original is wide open there. Related:
PostgreSQL - Writing dynamic sql in stored procedure that returns a result set
Table name as a PostgreSQL function parameter
That said, it would be more efficient to run a single UPDATE instead of updating one row per loop iteration. Consider building and executing a single statement.
I'm trying to use a temp table to update a database table in a stored procedure.
My client was throwing an error about an illegal null value, so I tried testing within SSMS and it told me that the name of the temp table was invalid (regardless of what I named it).
If I run the beginning and change the INSERT INTO SERVICE SELECT S.* to simply SELECT S.* and run the code after Declaring and Defining #OldServicesString (so I can leave out the ALTER/CREATE PROCEDURE line) it runs exactly as expected.
Here's the beginning of the SP:
ALTER PROCEDURE [dbo].[app_CreateNewServicesOldFSD] (#OldServicesStr nvarchar(max)) AS
SET NOCOUNT ON
DECLARE #User char(10) = (SELECT TOP 1 CREATED_BY_USER FROM BATCHLOG WHERE BPROCESS_ID = 3 ORDER BY ID DESC);
DECLARE #LastOldService int = (SELECT MAX(ID) FROM SERVICE);
SELECT TOP 0 * INTO #Service FROM SERVICE;
ALTER TABLE #Service
DROP COLUMN RECNUM;
INSERT INTO #Service exec dbo.app_NewServicesOldFSD
;WITH cteOldFSDsToCreate AS (
SELECT JobID.Item JobID, CONVERT(date,ServDate.Item,103) ServDate
FROM dbo.SplitStringToTable(#OldServicesStr,',',2) JobID
INNER JOIN dbo.SplitStringToTable(#OldServicesStr,',',2) ServDate ON JobID.Rw = ServDate.Rw AND JobID.Cl = 0 AND ServDate.Cl = 1
)
INSERT INTO SERVICE SELECT S.*
FROM #Service S
INNER JOIN cteOldFSDsToCreate N ON N.JobID = S.JOB_ID AND N.ServDate = S.DATE
DROP TABLE #Service
A useable and likely #OldServicesStr could be '11428,23/07/2019,11429,23/07/2019,15186,5/10/2019'
To test it in SSMS I opened a new Query and typed in
exec app_CreateNewServicesOldFSD '11428,23/07/2019,11429,23/07/2019,15186,5/10/2019'
And got the following error:
Warning: Null value is eliminated by an aggregate or other SET operation.
Msg 208, Level 16, State 0, Procedure app_CreateNewServicesOldFSD, Line 65 [Batch Start Line 7]
Invalid object name '#Service'.
Completion time: 2020-11-20T20:36:57.1356921+11:00
I know that is not Your case but in the sake of not forget, there is also a limitation using Biztalk WCF-Custom adapter with SQL Bindings and temp tables.
According to this site :
http://thoughtsofmarcus.blogspot.com/2010/11/calling-stored-procedures-from-biztalk.html
You need to SET FMTONLY OFF before creating temp tables and inserting into them and
SET FMTONLY ON before selecting from them as in example from below.
ALTER PROCEDURE [dbo].[FetchTestData]
(#a4 varchar(4))
AS
DECLARE #FmtOnlyIsSet bit = 0
IF (1=0) BEGIN SET #FmtOnlyIsSet = 1 END
IF #FmtOnlyIsSet = 1
SET FMTONLY OFF
SELECT t1, t2, t3 INTO #temp01 FROM Table_1
IF #FmtOnlyIsSet IS NULL
SET FMTONLY ON
SELECT t1, t2, t3 FROM #temp01
RETURN
I have written a stored procedure which executes a stored procedure and the result it gets has to be stored in a local temporary table. The Stored procedure gets created without giving any errors. But when I try to execute stored procedure, it returns the error that the temporary table is invalid object name.
CREATE PROCEDURE .dbo.CalulateETFWeights
-- Add the parameters for the stored procedure here
#CURR_DATE varchar(255),
#ETF_DATE datetime
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
--Select max(ETF_DATE) into #ETF_DATE from .dbo.ETF_LIST_V --where ETF_LOAD_DATE = #CURR_DATE
-- Insert statements for procedure here
SELECT TqaSecCode, GlobalSecurity, Cusip
into #tempetftable
from .map.v_get_tqa_security where cusip in (select distinct ETF_CUSIP from .dbo.ETF_LIST_V where ETF_LOAD_DATE = 'Mon Jun 17 14:15:09 BST 2019')
Insert into #tempPriceTable
exec .tqaif.sp_get_ds_price_usd
#sourceTable = '#tempetftable',
#startDate = '20181219',
#endDate = '20181219',
#frequency = 'D'
Insert into .dbo.ETFComponentWeights
Select
C.ETF_CUSIP as W_CAL_CUSIP,
C.STK_IDX as W_CAL_COMP,
C.STK_QUANT as W_CAL_SHARES,
CP.VALUE as W_CAL_PRICE,
(C.STK_QUANT * CP.VALUE_) as W_CAL_MVAL,
(C.STK_QUANT * CP.VALUE_)/SUM(C.STK_QUANT * CP.VALUE) over (partition by C.ETF_CUSIP) as W_CAL_WEIGHT,
#ETF_DATE as W_CAL_DATE
from .dbo.ETF_COMP_V C
inner join (Select E.CUSIP, P.Value_ from #tempPriceTable P inner join #tempetftable E on P.TqaSecCode = E.TqaSecCode) CP
on C.ETF_CUSIP = CP.CUSIP
So the error I get is
Invalid object name '#tempPriceTable'.
I don't understand why is this not working? Can anyone suggest what am I doing wrong here? and why the #tempetftable works fine. But #tempPriceTable here is not working in this scenario?
Syntax:
SELECT TqaSecCode, GlobalSecurity, Cusip
into #tempetftable
creates a new temp table and then inserts data into this new table.
Syntax:
Insert into #tempPriceTable
exec .tqaif.sp_get_ds_price_usd
is a regular "insert into" statement, which adds rows to existing table.
To use this syntax you need to create an empty temp table with correct schema beforehand.
So you need to do something like:
CREATE TABLE #tempPriceTable (your schema)
Insert into #tempPriceTable
exec .tqaif.sp_get_ds_price_usd
I've a Stored procedure which looks like this:
create procedure test as
begin
if exists(
select 1 from sys.columns
where Name = N'Column2'
and Object_ID = Object_ID(Table2')
)
select Column2 from Table2
end
I want to run this procedure on db where Column2 doesn't exist. I don't want to take existence check out of SP. Currently the error is :
Msg 207, Level 16, State 1, Procedure test, Line
39 [Batch Start Line 0] Invalid column name 'Column2'.
Is there any way to do so? Why yes and why not?
and why for instance if you check for existence table and select non-existent table that works?
Use dynamic SQL:
create procedure test as
begin
if exists (select 1
from sys.columns
where Name = N'Column2' and Object_ID = Object_ID('Table2')
)
begin
exec sp_executesql N'select Column2 from Table2';
end;
end;
I created this stored procedure in DB2 using Toad For DB2.
CREATE OR REPLACE PROCEDURE TEST_PROC
BEGIN
DECLARE GLOBAL TEMPORARY TABLE TEMP_TABLE_1(ID INT GENERATED ALWAYS AS IDENTITY,col001 CHAR(36)) NOT LOGGED WITH REPLACE;
DECLARE GLOBAL TEMPORARY TABLE TEMP_TABLE_2(ID INT GENERATED ALWAYS AS IDENTITY,col001 CHAR(36)) NOT LOGGED WITH REPLACE;
DECLARE GLOBAL TEMPORARY TABLE TEMP_TABLE_3(ID INT GENERATED ALWAYS AS IDENTITY,col001 CHAR(36)) NOT LOGGED WITH REPLACE;
INSERT INTO SESSION.TEMP_TABLE_1(col001) VALUES ('TABLE_1_ROW_1');
INSERT INTO SESSION.TEMP_TABLE_1(col001) VALUES ('TABLE_1_ROW_2');
INSERT INTO SESSION.TEMP_TABLE_1(col001) VALUES ('TABLE_1_ROW_3');
INSERT INTO SESSION.TEMP_TABLE_1(col001) VALUES ('TABLE_1_ROW_4');
INSERT INTO SESSION.TEMP_TABLE_2(col001) VALUES ('TABLE_2_ROW_1');
INSERT INTO SESSION.TEMP_TABLE_2(col001) VALUES ('TABLE_2_ROW_2');
INSERT INTO SESSION.TEMP_TABLE_2(col001) VALUES ('TABLE_2_ROW_3');
INSERT INTO SESSION.TEMP_TABLE_3(col001) VALUES ('TABLE_3_ROW_1');
BEGIN
DECLARE temp_cursor CURSOR WITH RETURN TO CLIENT FOR
SELECT tmp.* FROM(
SELECT id, col001 from SESSION.TEMP_TABLE_1
)tmp
Left join SESSION.TEMP_TABLE_2 tmp2 ON tmp2.id = tmp.id
AND EXISTS (SELECT 1 FROM SESSION.TEMP_TABLE_3 t3 WHERE t3.ID = 2);
OPEN temp_cursor;
END;
END;
But executing this stored procedure Call TEST_PROC() generates error.
DB2 Database Error: ERROR [56098] [IBM][DB2/NT64] SQL0727N An error occurred during implicit system action type "5". Information returned for the error includes SQLCODE "-338", SQLSTATE "42972" and message tokens "". SQLSTATE=56098
It does not give any error, if I
Change Left Join to INNER JOIN
Remove this condition AND EXISTS (SELECT 1 FROM SESSION.TEMP_TABLE_3 t3 WHERE t3.ID = 2)
but these two are required.
Any idea what am i doing wrong?