Stored procedure get stuck after move database - sql

I just dump data from production server to my local server for testing purpose. Our app uses a stored procedure with about 300 lines of sql. This procedure work fine in the server database, but it got stuck (running forever) every times i run it on my local database. Does anyone have any ideas about why it got stuck.
This is my command to dump data.
pg_dump --host localhost --port 5432 --username postgres --dbname test-new >D:\test5.sql
psql --host localhost --port 5432 --username postgres --dbname test-qa < file.sql
here is the Store Procedure
CREATE OR REPLACE FUNCTION public.insert_hm_ticket_statistic(v_sprint_id bigint)
RETURNS integer
LANGUAGE plpgsql
AS $$
DECLARE
v_ticket INT;
v_startsprint_date DATE;
v_end_date DATE;
v_current_date DATE;
v_first_activity_date DATE;
v_started DATE;
v_sprint_setting VARCHAR(255);
v_time_spent_second FLOAT;
v_remaining_estimate FLOAT;
v_time_logged_tmp FLOAT;
v_has_log INT;
v_time_logged_tk FLOAT;
v_oe_tk INT;
v_has_past_sprint INT;
v_oe_sprint INT;
v_complete_of_sprint FLOAT;
v_oe_tk_burnt FLOAT;
v_oe_sprint_burnt FLOAT;
v_project_complete FLOAT;
v_complete_tk FLOAT;
rl_cursor CURSOR FOR SELECT
tk.id,
tk.has_past_sprint,
cast(first_activity_date AS DATE)
FROM hm_ticket tk
WHERE sprint = v_sprint_id AND deleted = 0;
BEGIN
-- find start date and end date of sprint
SELECT
cast(start_date AS DATE),
cast(end_date AS DATE)
INTO v_startsprint_date, v_end_date
FROM hm_sprint
WHERE id = v_sprint_id AND status <> 'future';
-- find sprint setting
IF NOT exists(SELECT d.burn_down_statuses
FROM hm_sprint x, hm_setting c, hm_burn_down_status d
WHERE c.id = d.setting AND x.setting = c.id AND x.id = v_sprint_id)
THEN
v_sprint_setting :='xxx';
ELSE
SELECT string_agg(d.burn_down_statuses, ',')
INTO v_sprint_setting
FROM hm_sprint x, hm_setting c, hm_burn_down_status d
WHERE c.id = d.setting AND x.setting = c.id AND x.id = v_sprint_id;
END IF;
raise notice 'v_sprint_setting %', v_sprint_setting;
OPEN rl_cursor;
LOOP
FETCH rl_cursor INTO v_ticket, v_has_past_sprint, v_first_activity_date;
raise notice 'v_ticket: %', v_ticket;
EXIT WHEN NOT FOUND;
/*select cast(min(started) as date) into v_started
from hm_worklog
where ticket=v_ticket and cast(started as date) between v_startsprint_date and v_end_date;
if v_started is null then v_current_date:=v_startsprint_date;
else
v_current_date:=v_started;
end if;*/
v_current_date:=v_startsprint_date;
--- calculate remaining estimate, time logged of ticket
IF v_has_past_sprint = 0
THEN
SELECT
coalesce(remaining_estimate, 0),
coalesce(time_logged, 0)
INTO v_remaining_estimate, v_time_logged_tk
FROM hm_ticket
WHERE id = v_ticket;
ELSE
SELECT coalesce(time_logged, 0)
INTO v_time_logged_tmp
FROM hm_ticket
WHERE id = v_ticket;
--------------------------------------
SELECT
coalesce(remaining_estimate, 0),
v_time_logged_tmp - coalesce(time_logged, 0)
INTO v_remaining_estimate, v_time_logged_tk
FROM hm_ticket_past_sprint
WHERE ticket = v_ticket;
END IF;
raise notice '----------v_has_past_sprint: %', v_has_past_sprint;
raise notice '----------v_time_logged_tmp: %', v_time_logged_tmp;
raise notice '----------v_time_logged_tk: %', v_time_logged_tk;
raise notice '----------v_remaining_estimate: %', v_remaining_estimate;
-- calculate oe of ticket
IF v_has_past_sprint = 0
THEN
SELECT cast(CASE WHEN coalesce(original_estimate, 0) = 0
THEN coalesce(time_logged, 0)
ELSE original_estimate
END
AS FLOAT)
INTO v_oe_tk
FROM hm_ticket
WHERE id = v_ticket;
ELSE
SELECT coalesce(time_logged, 0)
INTO v_time_logged_tmp
FROM hm_ticket
WHERE id = v_ticket;
--------------------------------------
SELECT cast(CASE WHEN coalesce(original_estimate, 0) = 0
THEN v_time_logged_tmp - coalesce(time_logged, 0)
ELSE original_estimate
END
AS FLOAT)
INTO v_oe_tk
FROM hm_ticket_past_sprint
WHERE ticket = v_ticket;
END IF;
raise notice 'v_oe_tk: %',v_oe_tk;
/*########################################################################## START TO LOOP CURRENT DATE #############################################################################*/
WHILE v_current_date <= v_end_date LOOP
--- calculate time_spent_seconds from start sprint
IF NOT exists(SELECT id
FROM hm_worklog
WHERE ticket = v_ticket AND cast(started AS DATE) BETWEEN v_startsprint_date AND v_current_date)
THEN
v_time_spent_second:=0;
ELSE
SELECT cast(sum(time_spent_seconds) AS FLOAT)
INTO v_time_spent_second
FROM hm_worklog
WHERE ticket = v_ticket AND cast(started AS DATE) BETWEEN v_startsprint_date AND v_current_date
GROUP BY ticket;
END IF;
raise notice 'v_time_spent_second: %', v_time_spent_second;
--calculate % complete of ticket/day
IF NOT v_current_date = v_end_date THEN
IF NOT exists(SELECT date FROM hm_ticket_history WHERE ticket = v_ticket AND cast(date AS DATE) = v_current_date)
then
-- FIND STATUS OF TICKET IN SETTING. 0: NO STATUS EXIST -> FORMULAR SHOULD BE APPLIED , <>0 : EXIST--> SET COMPLETE TK = 0
SELECT CASE WHEN (position(upper(trim(status)) IN upper(trim(v_sprint_setting))) = 0)
THEN CASE WHEN v_remaining_estimate = 0 AND v_time_logged_tk <> 0 THEN 80
WHEN v_remaining_estimate = 0 AND v_time_logged_tk = 0 THEN 0
WHEN (v_remaining_estimate + v_time_logged_tk) = 0 THEN 0
ELSE round(cast(v_time_spent_second * 100 / (v_time_logged_tk + v_remaining_estimate) AS NUMERIC), 2)
END
ELSE 100
END AS complete
INTO v_complete_tk
FROM hm_ticket
WHERE id = v_ticket;
ELSE
SELECT CASE WHEN (position(upper(trim(status)) IN upper(trim(v_sprint_setting))) = 0)
THEN CASE WHEN v_remaining_estimate = 0 AND v_time_logged_tk <> 0 THEN 80
WHEN v_remaining_estimate = 0 AND v_time_logged_tk = 0 THEN 0
WHEN (v_remaining_estimate + v_time_logged_tk) = 0 THEN 0
ELSE round(cast(v_time_spent_second * 100 / (v_time_logged_tk + v_remaining_estimate) AS NUMERIC), 2)
END
ELSE 100
END AS complete
INTO v_complete_tk
FROM hm_ticket_history
WHERE ticket = v_ticket AND cast("date" AS DATE)= v_current_date;
END IF;
ELSE
--NOTE: IF V_CURRENT_DATE == END-DATE-OF-SPRINT, COMPLETE % WILL BE CALCULATED BASE ON LATEST TICKET STATUS, NOT LAST-DAY-OF-SPRINT TICKET STATUS
IF NOT exists(SELECT date FROM hm_ticket_history WHERE ticket = v_ticket AND cast(date AS DATE) = v_current_date)
then
SELECT CASE WHEN (position(upper(trim(status)) IN upper(trim(v_sprint_setting))) = 0)
THEN CASE WHEN v_remaining_estimate = 0 AND v_time_logged_tk <> 0 THEN 80
WHEN v_remaining_estimate = 0 AND v_time_logged_tk = 0 THEN 0
WHEN (v_remaining_estimate + v_time_logged_tk) = 0 THEN 0
ELSE round(cast(v_time_spent_second * 100 / (v_time_logged_tk + v_remaining_estimate) AS NUMERIC), 2)
END
ELSE 100
END AS complete
INTO v_complete_tk
FROM hm_ticket
WHERE id = v_ticket;
else
SELECT CASE WHEN (position(upper(trim(status)) IN upper(trim(v_sprint_setting))) = 0)
THEN CASE WHEN v_remaining_estimate = 0 AND v_time_logged_tk <> 0 THEN 80
WHEN v_remaining_estimate = 0 AND v_time_logged_tk = 0 THEN 0
WHEN (v_remaining_estimate + v_time_logged_tk) = 0 THEN 0
ELSE round(cast(v_time_spent_second * 100 / (v_time_logged_tk + v_remaining_estimate) AS NUMERIC), 2)
END
ELSE 100
END AS complete
INTO v_complete_tk
FROM hm_ticket_history
WHERE ticket = v_ticket order by date desc limit 1;
END IF;
END IF;
if v_complete_tk > 100 then v_complete_tk := 100;
end if;
raise notice 'v_sprint_setting: %', v_sprint_setting;
raise notice 'v_complete_tk: %', v_complete_tk;
raise notice '---------------------------------';
-- check has log
IF exists(SELECT id
FROM hm_worklog
WHERE cast(started AS DATE) = cast(v_current_date AS DATE) AND ticket = v_ticket)
THEN
v_has_log := 1;
ELSE
v_has_log := 0;
END IF;
--raise notice 'v_has_log: %', v_has_log;
-- calculate oe of sprint
SELECT sum(x.oe)
INTO v_oe_sprint
FROM
(
SELECT CASE WHEN coalesce(original_estimate, 0) = 0
THEN coalesce(time_logged, 0)
ELSE coalesce(original_estimate, 0)
END oe
FROM hm_ticket
WHERE sprint = v_sprint_id AND cast(first_activity_date AS DATE) <= v_current_date
AND has_past_sprint = 0
UNION ALL
SELECT CASE WHEN coalesce(b.original_estimate, 0) = 0
THEN coalesce(a.time_logged - b.time_logged)
ELSE coalesce(b.original_estimate, 0)
END oe
FROM hm_ticket a, hm_ticket_past_sprint b
WHERE a.id = b.ticket AND a.sprint = v_sprint_id AND cast(a.first_activity_date AS DATE) <= v_current_date
AND a.has_past_sprint = 1
) x;
-- raise notice 'v_oe_sprint: %', v_oe_sprint;
-- calculate v_oe_tk_burnt
SELECT CASE WHEN v_time_spent_second = 0 OR v_oe_tk = 0
THEN 0
ELSE round(cast((v_time_spent_second * 100 / v_oe_tk) AS NUMERIC), 2)
END
INTO v_oe_tk_burnt;
--raise notice 'v_oe_tk_burnt: %', v_oe_tk_burnt;
-- calculate v_oe_sprint_burnt
IF v_oe_sprint = 0
THEN
v_oe_sprint_burnt:=100;
ELSE
SELECT round(cast((v_time_spent_second * 100 / v_oe_sprint) AS NUMERIC), 2)
INTO v_oe_sprint_burnt;
END IF;
--raise notice 'v_oe_sprint_burnt: %', v_oe_sprint_burnt;
-- calculate v_project_complete
IF v_oe_sprint = 0
THEN
v_project_complete:=100;
ELSE
SELECT round(cast((v_complete_tk * v_oe_tk / v_oe_sprint) AS NUMERIC), 2)
INTO v_project_complete;
END IF;
-- raise notice 'v_project_complete: %', v_project_complete;
IF v_current_date >= v_first_activity_date
THEN
INSERT INTO hm_ticket_statistic (complete, date, has_log, last_modified, original_estimate_burnt, original_estimate_project_burnt, project_complete, status, ticket, sprint)
VALUES
(v_complete_tk, cast(v_current_date AS DATE), v_has_log, current_timestamp, v_oe_tk_burnt, v_oe_sprint_burnt,
v_project_complete, 1, v_ticket, v_sprint_id)
ON CONFLICT (date, ticket, sprint)
DO UPDATE
SET complete = v_complete_tk,
has_log = v_has_log,
original_estimate_burnt = v_oe_tk_burnt,
original_estimate_project_burnt = v_oe_sprint_burnt,
project_complete = v_project_complete;
END IF;
v_current_date:= v_current_date + INTERVAL '24 hours';
EXIT WHEN NOT found;
END LOOP;
END LOOP;
CLOSE rl_cursor;
RETURN 0;
END;
Also, if you see anything that can be improved in the code, please suggest me.

Try running analyze on the local database, after restoring the dump. This updates statistics.

Finally found the bug. It is a deadlock bug, i used Synchronized on function way too much, they start to get stuck. The production server still get the same problem, i just don't see it. So i try to use Synchronized more selectively, reduce the size of functions that Synchronized on. Then it is fixed.

Related

Declare variable PostgreSQL

I'm trying to declare a variable which I will pass a value, but even with a single example, I got an different errors. For example: unexpected end of function definition at end of input.
I assume that the reason is that I am passing the value to a temporary table, but I don't know how to fix it
DO $$
DECLARE var2 varchar(20) := 'dzien';
BEGIN
SELECT
CASE WHEN var2 = 'dzien' THEN to_date((to_char(czasRozmowy, 'YYYY/MM/DD' )),'YYYY/MM/DD') ELSE to_date('0000/00/00', 'YYYY/MM/DD')
END as data_,
COUNT(DISTINCT(lekta_call_id)) iloscRozmow
,COUNT(DISTINCT(czasProcesu)) iloscProceso
,SUM(czySukces) iloscRozmowSukces
,SUM(czyTransfer) iloscRozmowTransfer
,SUM(czyRozlaczone) iloscRozmowRozlaczonych
,SUM(czyWsylanySMS) iloscSMS
FROM
(
SELECT
c.start_time czasRozmowy
,d.process_start_time czasProcesu
,c.l_call_id l_call_id
,CASE WHEN end_call_status=3 THEN 1 ELSE 0 END czySukces
,CASE WHEN end_call_status=2 THEN 1 ELSE 0 END czyTransfer
,CASE WHEN end_call_status=1 THEN 1 ELSE 0 END czyRozlaczone
,CASE WHEN send_sms=true THEN 1 ELSE 0 END czyWsylanySMS
FROM "Conversat" C
left join dialogues_details d on c.l_call_id=d.l_call_id
) as tabelka
group by data_
END $$;
Try this
CREATE OR REPLACE FUNCTION _get_result(
_var2 VARCHAR DEFAULT NULL
) RETURNS TABLE (
iloscRozmow INTEGER,
iloscProceso INTEGER,
iloscRozmowSukces INTEGER,
iloscRozmowTransfer INTEGER,
iloscRozmowRozlaczonych INTEGER,
iloscSMS INTEGER,
) AS $$
BEGIN
RETURN QUERY SELECT
CASE WHEN _var2 = 'dzien' THEN to_date((to_char(czasRozmowy, 'YYYY/MM/DD' )),'YYYY/MM/DD') ELSE to_date('0000/00/00', 'YYYY/MM/DD')
END as data_,
COUNT(DISTINCT(lekta_call_id)) iloscRozmow,
COUNT(DISTINCT(czasProcesu)) iloscProceso,
SUM(czySukces) iloscRozmowSukces,
SUM(czyTransfer) iloscRozmowTransfer,
SUM(czyRozlaczone) iloscRozmowRozlaczonych,
SUM(czyWsylanySMS) iloscSMS
FROM
(
SELECT
c.start_time czasRozmowy,
d.process_start_time czasProcesu,
c.l_call_id l_call_id,
CASE WHEN end_call_status=3 THEN 1 ELSE 0 END czySukces,
CASE WHEN end_call_status=2 THEN 1 ELSE 0 END czyTransfer,
CASE WHEN end_call_status=1 THEN 1 ELSE 0 END czyRozlaczone,
CASE WHEN send_sms=true THEN 1 ELSE 0 END czyWsylanySMS
FROM "Conversat" C
left join dialogues_details d on c.l_call_id=d.l_call_id
) as tabelka
group by data_;
END
$$ LANGUAGE 'plpgsql';
SELECT * FROM _get_result('dzien');

Execute Select query in end of function

I have CTE as bellow,
WITH extract_dow AS (
SELECT EXTRACT(DOW FROM TIMESTAMP '1994-03-15'::DATE) AS dow
)
,name_day AS(
SELECT
CASE WHEN dow = 0 THEN (SELECT 'Minggu'::TEXT AS day)
ELSE
CASE WHEN dow = 1 THEN (SELECT 'Senin'::TEXT AS day)
ELSE
CASE WHEN dow = 2 THEN (SELECT 'Selasa'::TEXT AS day)
ELSE
CASE WHEN dow = 3 THEN (SELECT 'Rabu'::TEXT AS day)
ELSE
CASE WHEN dow = 4 THEN (SELECT 'Kamis'::TEXT AS day)
ELSE
CASE WHEN dow = 5 THEN (SELECT 'Jumat'::TEXT AS day)
ELSE
CASE WHEN dow = 6 THEN (SELECT 'Sabtu'::TEXT AS day)
ELSE (SELECT 'Inputan Salah'::TEXT AS day)
END
END
END
END
END
END
END
FROM extract_dow
)
, extract_age AS (
SELECT ((CURRENT_DATE - '1994-03-15'::DATE)/365) AS age
)
SELECT 'Anda Lahir :' || a.day || ',' || b.age || ' Tahun' AS "Keterangan" FROM name_day a, extract_age b
Its to generate day in text of date '1994-03-15' and age calculate from current, when its execute we have in output:
"Anda Lahir :Selasa,24 Tahun"
When I Try to convert it to function as bellow:
> -- Function: function_birthday(date)
>
> -- DROP FUNCTION function_birthday(date);
>
> CREATE OR REPLACE FUNCTION function_birthday(inputan date)
> RETURNS text AS
> $BODY$
> DECLARE
> perintah text;
> BEGIN
>
> perintah := $sql$
>
> WITH extract_dow AS ( SELECT EXTRACT(DOW FROM TIMESTAMP '$sql$ || inputan || $sql$'::DATE) AS dow )
> ,name_day AS( SELECT CASE WHEN dow = 0 THEN (SELECT 'Minggu'::TEXT AS day)
> ELSE CASE WHEN dow = 1 THEN (SELECT 'Senin'::TEXT AS day)
> ELSE
> CASE WHEN dow = 2 THEN (SELECT 'Selasa'::TEXT AS day)
> ELSE
> CASE WHEN dow = 3 THEN (SELECT 'Rabu'::TEXT AS day)
> ELSE
> CASE WHEN dow = 4 THEN (SELECT 'Kamis'::TEXT AS day)
> ELSE
> CASE WHEN dow = 5 THEN (SELECT 'Jumat'::TEXT AS day)
> ELSE
> CASE WHEN dow = 6 THEN (SELECT 'Sabtu'::TEXT AS day)
> ELSE (SELECT 'Inputan Salah'::TEXT AS day)
> END
> END
> END
> END
> END
> END
> END FROM extract_dow )
>
>
> , extract_age AS ( SELECT ((CURRENT_DATE - '$sql$ || inputan || $sql$'::DATE)/365) AS age)
> SELECT 'Anda Lahir :' || a.day || ',' || b.age || ' Tahun' AS "Keterangan" FROM name_day a, extract_age b
>
> RETURN *;
> $sql$;
> EXECUTE perintah;
> END;
> $BODY$
> LANGUAGE plpgsql VOLATILE COST 100;
> ALTER FUNCTION function_birthday(date)
> OWNER TO postgres;
But when im execute it with
SELECT public.function_birthday('1994-03-15');
I have error
ERROR: syntax error at or near "RETURN"
LINE 36: RETURN *;
CONTEXT: PL/pgSQL function function_birthday(date) line 43 at EXECUTE statement
********** Error **********
ERROR: syntax error at or near "RETURN"
SQL state: 42601
Context: PL/pgSQL function function_birthday(date) line 43 at EXECUTE statement
My question is, where is the error from my function, or i am write in wrong structure of the function, i had searching and looking for to solve it (How to convert my CTE to function)?
Thanks for Help, ^_^
You could try:
> -- Function: function_birthday(date)
>
> -- DROP FUNCTION function_birthday(date);
>
> CREATE OR REPLACE FUNCTION function_birthday(inputan date)
> RETURNS text AS
> $BODY$
> DECLARE
> perintah text;
> result text;
> BEGIN
>
> perintah := $sql$
>
> WITH extract_dow AS ( SELECT EXTRACT(DOW FROM TIMESTAMP '$sql$ || inputan || $sql$'::DATE) AS dow )
> ,name_day AS( SELECT CASE WHEN dow = 0 THEN (SELECT 'Minggu'::TEXT AS day)
> ELSE CASE WHEN dow = 1 THEN (SELECT 'Senin'::TEXT AS day)
> ELSE
> CASE WHEN dow = 2 THEN (SELECT 'Selasa'::TEXT AS day)
> ELSE
> CASE WHEN dow = 3 THEN (SELECT 'Rabu'::TEXT AS day)
> ELSE
> CASE WHEN dow = 4 THEN (SELECT 'Kamis'::TEXT AS day)
> ELSE
> CASE WHEN dow = 5 THEN (SELECT 'Jumat'::TEXT AS day)
> ELSE
> CASE WHEN dow = 6 THEN (SELECT 'Sabtu'::TEXT AS day)
> ELSE (SELECT 'Inputan Salah'::TEXT AS day)
> END
> END
> END
> END
> END
> END
> END FROM extract_dow )
>
>
> , extract_age AS ( SELECT ((CURRENT_DATE - '$sql$ || inputan || $sql$'::DATE)/365) AS age)
> SELECT 'Anda Lahir :' || a.day || ',' || b.age || ' Tahun' AS "Keterangan" FROM name_day a, extract_age b
>
> $sql$;
> EXECUTE perintah INTO result;
> RETURN result;
> END;
> $BODY$
> LANGUAGE plpgsql VOLATILE COST 100;
> ALTER FUNCTION function_birthday(date)
> OWNER TO postgres;

How to use part of a query inside a variable Oracle Function

I'm trying to use a part of a query into a variable , because I have many ifs to prepare the query , but I have not used something like this.
FUNCTION f_rel_vendas_importacao(vTP_DADOS in varchar2, nCODIGO in number, dDT_COMPRA_INI in DATE, dDT_COMPRA_FIM in DATE, dDT_EFETIVACAO_INI in DATE, dDT_EFETIVACAO_FIM in DATE) RETURN number is
nRetorno number(14,2);
vSTRING VARCHAR2(2000);
begin
IF vTP_DADOS = 'VL_COMISSAO' THEN
vSTRING := 'SUM( DECODE( CPF.CD_MOEDA, 1, CPF.VL_COTACAO_UNIT * CPF.QTDE_COMPRA, ( SELECT Imp_Pack.fu_converte_moeda_ORACLE( CPF.CD_MOEDA, 1, CDT.DT_RECEBIMENTO, CPF.VL_COTACAO_UNIT, 1) * CPF.QTDE_COMPRA FROM dual ) ) )';
END IF;
IF vTP_DADOS = 'QTD_VENDA_SELECTCHEMIE_PERIODO' THEN
vSTRING := 'count(*)';
END IF;
SELECT
vSTRING
INTO
nRetorno
FROM
COMPRA_PROD_FORN CPF,
COMPRA_DATA CDT
WHERE
(CDT.DT_RECEBIMENTO >= dDT_COMPRA_INI AND CDT.DT_RECEBIMENTO <= dDT_COMPRA_FIM) AND
CDT.CD_COMPRA = CPF.CD_COMPRA AND
CDT.CD_TP_DATA = 7 AND
CPF.CD_FORNECEDOR = nCODIGO;
Return nRetorno;
end
f_rel_vendas_importacao;
When you SELECT vString, the result is the content of the variable vString. It doesn't make any attempt to interpret that content as a column or expression. You are best off placing those expressions directly into the query.
IF vTP_DADOS = 'VL_COMISSAO' THEN
SELECT
SUM( DECODE( CPF.CD_MOEDA, 1,
CPF.VL_COTACAO_UNIT * CPF.QTDE_COMPRA,
( SELECT Imp_Pack.fu_converte_moeda_ORACLE( CPF.CD_MOEDA, 1,
CDT.DT_RECEBIMENTO, CPF.VL_COTACAO_UNIT, 1) *
CPF.QTDE_COMPRA
FROM dual ) ) )
INTO
nRetorno
FROM
COMPRA_PROD_FORN CPF,
COMPRA_DATA CDT
WHERE
(CDT.DT_RECEBIMENTO >= dDT_COMPRA_INI AND
CDT.DT_RECEBIMENTO <= dDT_COMPRA_FIM) AND
CDT.CD_COMPRA = CPF.CD_COMPRA AND
CDT.CD_TP_DATA = 7 AND
CPF.CD_FORNECEDOR = nCODIGO;
END IF;
IF vTP_DADOS = 'QTD_VENDA_SELECTCHEMIE_PERIODO' THEN
SELECT count(*)
INTO
nRetorno
FROM
COMPRA_PROD_FORN CPF,
COMPRA_DATA CDT
WHERE
(CDT.DT_RECEBIMENTO >= dDT_COMPRA_INI AND
CDT.DT_RECEBIMENTO <= dDT_COMPRA_FIM) AND
CDT.CD_COMPRA = CPF.CD_COMPRA AND
CDT.CD_TP_DATA = 7 AND
CPF.CD_FORNECEDOR = nCODIGO;
END IF;

how to change stored procedure into table valued function?

This is my stored procedure that I want to change into a table-valued function. I don't know how to create a table-valued function, please help me
ALTER procedure [dbo].[GENRATE_BATCHNO]
#StrBatchNo varchar(200) output,
#BatchNum bigint output,
#RetType bigint output,
#Fid int,
#WcID int,
#PrCompID bigint,
#BsProductID bigint,
#CreationDt datetime
as
begin
Declare #RestartFrom int, #BatchID bigint,#BatchMaxVal bigint,#ParaType int, #BatchValue varchar(50),#BatchFormat varchar(10),
#Digits bigint,#BsParaID int,#StrBatchVal varchar(200),#StrVal varchar(200), #Type bigint, #Base int,#CompanyId int, #EffDate Date
if exists (select 'x' from Tblbatchnosetting where baseprid=#BsProductID and PrCompID=#PrCompID and wcid=#WcID and effdate <= #CreationDt )
Declare Cur_SttgMaster Cursor For Select RestartFrom,BatchID, Isnull(type,1),Base, CompanyId as Type,EffDate from Tblbatchnosetting where baseprid=#BsProductID and PrCompID=#PrCompID and wcid=#WcID
and effdate <= #CreationDt order by effdate desc
else
begin
Declare Cur_SttgMaster Cursor For Select RestartFrom,BatchID, Isnull(Type,1) as Type,Base,CompanyId,EffDate from Tblbatchnosetting where Companyid in (Select MfgID from TblBaseProduct where BsProductID=#BsProductID) and Base=1 and PrCompID=#PrCompID and wcid=#WcID
and effdate <= #CreationDt order by effdate desc
end
open Cur_SttgMaster
Fetch Next From Cur_SttgMaster Into #RestartFrom, #BatchID, #Type, #Base, #CompanyId,#EffDate
Close Cur_SttgMaster
Deallocate Cur_SttgMaster
Set #RetType = #Type
If #RestartFrom <> 0
begin
if #Base=1
begin
if #RestartFrom=1 --- Month ReStart
Select #BatchMaxVal = isnull(Max(BatchNum),0) from tblbatchmaster where PrCompID=#PrCompID and BasePrid in (Select Bsproductid from TblBaseProduct where Mfgid=#CompanyId) and Wcid=#Wcid
and fid=#Fid and month(CreatDate)=Month(#CreationDt)
else if #RestartFrom=2 --- Yearly ReStart
Select #BatchMaxVal = isnull(Max(BatchNum),0) from tblbatchmaster where PrCompID=#PrCompID and BasePrid in (Select Bsproductid from TblBaseProduct where Mfgid=#CompanyId) and Wcid=#Wcid
and Year(CreatDate)=Year(#CreationDt) and CREATDATE >=#EffDate
else if #RestartFrom=3 --- never ReStart
Select #BatchMaxVal = isnull(Max(BatchNum),0) from tblbatchmaster where PrCompID=#PrCompID and BasePrid in (Select Bsproductid from TblBaseProduct where Mfgid=#CompanyId) and Wcid=#Wcid
end
else if #Base=2
BEGIN
if #RestartFrom=1 --- Month ReStart
Select #BatchMaxVal = isnull(Max(BatchNum),0) from tblbatchmaster where PrCompID=#PrCompID and BasePrid=#BsProductID and Wcid=#Wcid
and fid=#Fid and month(CreatDate)=Month(#CreationDt)
else if #RestartFrom=2 --- Yearly ReStart
Select #BatchMaxVal = isnull(Max(BatchNum),0) from tblbatchmaster where PrCompID=#PrCompID and BasePrid=#BsProductID and Wcid=#Wcid
and Year(CreatDate)=Year(#CreationDt) and CREATDATE >=#EffDate
else if #RestartFrom=3 --- Never ReStart
Select #BatchMaxVal = isnull(Max(BatchNum),0) from tblbatchmaster where PrCompID=#PrCompID and BasePrid=#BsProductID and Wcid=#Wcid
END
Declare Cur_SttgDetail Cursor For Select BsParaID,ParaType,BatchValue,BatchFormat,Digits from TblBatchNoSettingDetail where BatchID=#BatchID order by SeqNo
Open Cur_SttgDetail
Fetch Next From Cur_SttgDetail Into #BsParaID,#ParaType,#BatchValue,#BatchFormat,#Digits
Set #StrVal=''
While ##Fetch_Status=0
begin
Set #StrBatchVal=''
if #BsParaID=6 -- for Year
begin
if upper(ltrim(rtrim(#BatchFormat)))='Y'
Set #StrBatchVal=Cast(Cast(right(year(#CreationDt),1)as int) as varchar(2))
else if upper(ltrim(rtrim(#Batchformat)))='YY'
Set #StrBatchVal=Cast(right(year(#CreationDt),2) as varchar(2))
else if upper(ltrim(rtrim(#Batchformat)))='YYYY'
Set #StrBatchVal=Cast(year(#CreationDt) as varchar(4))
end
else if #BsParaID=7 -- For Month
begin
if upper(ltrim(rtrim(#BatchFormat)))='MM'
if Cast(month(#CreationDt) as int) < 10
Set #StrBatchVal= '0' + Cast(month(#CreationDt)as varchar(2))
else
Set #StrBatchVal= Cast(month(#CreationDt)as varchar(2))
else if Upper(ltrim(rtrim(#BatchFormat)))='A'
Set #StrBatchVal=(Select Case cast(Month(#CreationDt)as int)
when 1 then 'A'
when 2 then 'B'
when 3 then 'C'
when 4 then 'D'
when 5 then 'E'
when 6 then 'F'
when 7 then 'G'
when 8 then 'H'
when 9 then 'I'
when 10 then'J'
when 11 then'K'
when 12 then'L'
end)
end
else if #BsParaID=8
begin
if #BatchMaxVal=0
begin
if #RestartFrom=3
begin
if #Batchvalue>=100
begin
Set #StrBatchVal = #BatchValue
Set #BatchNum=Cast(#BatchValue as bigint)
end
else
begin
Set #StrBatchVal = Cast(replicate('0',#Digits-len(#BatchValue)) as varchar(10)) + #BatchValue
Set #BatchNum=Cast(#BatchValue as bigint)
end
end
else
begin
Set #StrBatchVal = Cast(replicate('0',#Digits-len(#BatchValue)) as varchar(10)) + #BatchValue
Set #BatchNum=Cast(#BatchValue as bigint)
end
end
else
begin
Set #BatchMaxVal=#BatchMaxVal+1
Set #StrBatchVal = cast(replicate('0',#Digits-len(cast(#BatchMaxVal as varchar(10)))) as varchar(10)) + Cast(#BatchMaxVal as varchar(10))
Set #BatchNum=#BatchMaxVal
end
end
if #StrBatchVal=''
Set #StrBatchVal=#BatchValue
Set #StrVal = #StrVal + #StrBatchVal
Fetch Next From Cur_SttgDetail Into #BsParaID,#ParaType,#BatchValue,#BatchFormat,#Digits
end
Close Cur_SttgDetail
Deallocate Cur_SttgDetail
Set #StrBatchNo = cast(#StrVal as varchar(200))
end
Return #RetType
Return #BatchNum
Return #StrBatchNo
end
Can you tell me how to call this stored procedure I try but fail
string strsql = "Exec [dbo].[GENRATE_BATCHNO] " + Fid + "," + WcID + "," + PrCompID + "," + BsProductID + ",'" + CreationDate + "' ";
Reader = dc.GetReader(strsql);
There are two ways
rewrite your sp as a table value function (http://msdn.microsoft.com/en-us/library/ms187650.aspx)
using an ugly way of OpenQuery see below example
CREATE FUNCTION dbo.myfunction
(#f1 char(14), #d1 smalldatetime, #tip char(1))
RETURNS TABLE
AS
RETURN
(SELECT * FROM openquery('SERVER', 'exec dbo.sp #f1, #d1, #tip'))

SQL Stored procedure if (#variable = 0) doesn't work

I've created a Stored procedure with some variables and a nested if statement.
When I call the Stored procedure from my program and check the returned dataset for the returned values, my dataset is empty while there should be records in it. After some testing I noticed when the statement if (#PoolID = 0) is tested and #PoolID is 0, it won't go trough the if statement... So whenever I set the variable poolid to 0 in my code I get the results from the else statement...
Anybody who knows what's going wrong?
Thx
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[Pool_select]
#PartnerCode nvarchar(8),
#GebrID int,
#PoolID int,
#Bevoegdheid int
AS
IF (#PoolID = 0)
BEGIN
IF (#Bevoegdheid < 3)
BEGIN
SELECT
p.*,
pr.poolrecht
FROM racpPool p, racpPoolrecht pr
WHERE
p.poolid = pr.poolid and
p.PartnerCode = #PartnerCode and
pr.poolrecht > 0 and
p.actief = 1 and
pr.GebrID = #GebrID
END
ELSE
BEGIN
SELECT *
FROM racpPool p
WHERE standaardpool = 1
and partnercode = #PartnerCode
END
END
ELSE
BEGIN
IF (#Bevoegdheid < 3)
BEGIN
SELECT
p.*,
pr.poolrecht
FROM racpPool p, racpPoolrecht pr
WHERE
p.poolid = pr.poolid and
p.PartnerCode = #PartnerCode and
pr.poolrecht > 0 and
p.actief = 1 and
pr.GebrID = #GebrID and
p.PoolID = #PoolID
END
ELSE IF (#Bevoegdheid >= 3)
BEGIN
SELECT *
FROM racpPool p
WHERE PoolID = #PoolID
END
END
You could rewrite it as one single select of 4-part UNION ALL.
I also notice that your conditions are not comprehensive, not sure if that is intentional.
In the 2nd branch of #PoolID = 0 , the tests are specifically #Bevoegdheid < 3 and #Bevoegdheid >= 3 (instead of ELSE ) which will do nothing if #Bevoegdheid IS NULL
The optimizer will only run the branch that fits the criteria marked with <<<
ALTER PROCEDURE [dbo].[Pool_select]
#PartnerCode nvarchar(8),
#GebrID int,
#PoolID int,
#Bevoegdheid int
-- WITH RECOMPILE -- << may need this
AS
SELECT
p.*,
pr.poolrecht
FROM racpPool p, racpPoolrecht pr
WHERE
p.poolid = pr.poolid and
p.PartnerCode = #PartnerCode and
pr.poolrecht > 0 and
p.actief = 1 and
pr.GebrID = #GebrID
AND #PoolID = 0 and #Bevoegdheid < 3 --- <<<
UNION ALL
SELECT *, NULL
FROM racpPool p
WHERE standaardpool = 1
and partnercode = #PartnerCode
AND #PoolID = 0 and IsNull(#Bevoegdheid,4) >= 3 --- <<<
UNION ALL
SELECT
p.*,
pr.poolrecht
FROM racpPool p, racpPoolrecht pr
WHERE
p.poolid = pr.poolid and
p.PartnerCode = #PartnerCode and
pr.poolrecht > 0 and
p.actief = 1 and
pr.GebrID = #GebrID and
p.PoolID = #PoolID
AND Isnull(#PoolID,-1) <> 0 AND #Bevoegdheid < 3 --- <<<
UNION ALL
SELECT *, NULL
FROM racpPool p
WHERE PoolID = #PoolID
AND Isnull(#PoolID,-1) <> 0 AND #Bevoegdheid >= 3 --- <<<