Creating function in PostgreSQL - postgresql

I am trying to create the following procedure in Aginity workbench with DBMS PostgreSQL 8.0.2
CREATE PROCEDURE Step1_data_main
(
#startdate NVARCHAR(MAX),
#enddate NVARCHAR(MAX),
#season NVARCHAR(MAX)
) AS
SELECT level1_idnt,day_dt, sum(sls_qty) as sum_units,sum(sls_amnt_price) as sum_sales
FROM md1.loc_sku_dy_act_pos_full_v2
WHERE seasn_cd = '+#season+' and day_dt >= ''+#startdate+'' and day_dt <= ''+#enddate+''
GROUP_BY level1_idnt, day_dt;
END
EXEC Step1_data_main
'2015-03-01 00:00:00',
'2015-09-30 00:00:00',
'2'
GO
However I am getting the following error
syntax error at or near "PROCEDURE"
Any guidance on this will be greatly appreciated
EDIT
I am working in Aginity Workbench with PostgreSQL I had previously incorrectly said I am using mysql workbench.

This should work for you:
CREATE PROCEDURE `Step1_data_main`(
startdate NVARCHAR(1000),
enddate NVARCHAR(1000),
season NVARCHAR(1000)
)
begin
SELECT level1_idnt,day_dt, sum(sls_qty) as sum_units,sum(sls_amnt_price) as sum_sales
FROM md1.loc_sku_dy_act_pos_full_v2
WHERE seasn_cd = cast(season as UNSIGNED) and
day_dt >= cast(startdate as datetime) and
day_dt <= cast(enddate as datetime)
GROUP BY level1_idnt, day_dt;
END$$

You should try in this way, Yo are using sql server syntax in mysql thats why getting error.
This is for MySQL
DELIMITER $$
CREATE PROCEDURE Step1_data_main(
startdate NVARCHAR(20),
enddate NVARCHAR(20),
season NVARCHAR(20))
BEGIN
SELECT level1_idnt,day_dt, sum(sls_qty) as sum_units,sum(sls_amnt_price) as sum_sales
FROM md1.loc_sku_dy_act_pos_full_v2
WHERE seasn_cd = '+#season+' and day_dt >= ''+#startdate+''
and day_dt <= ''+#enddate+''
GROUP BY level1_idnt, day_dt;
END$$
Update1: This is for SQL Server
Create PROCEDURE Step1_data_main(
#startdate NVARCHAR(20),
#enddate NVARCHAR(20),
#season NVARCHAR(20)
)
AS
BEGIN
SELECT level1_idnt,day_dt, sum(sls_qty) as sum_units,sum(sls_amnt_price) as sum_sales
FROM md1.loc_sku_dy_act_pos_full_v2
WHERE seasn_cd = '+#season+' and day_dt >= ''+#startdate+''
and day_dt <= ''+#enddate+''
GROUP BY level1_idnt, day_dt;
END;

Related

Return both out value and query select value in postgres

Here is my sql server sample procedure while migrating to postgres sql i am unable to return output value and
return query value.I want to return SUCCESS and followed by query value
ALTER PROCEDURE [dbo].[VERIFY](
#P_VER_NO VARCHAR(5) ,
#P_SOLID VARCHAR(6) ,
#P_ID VARCHAR(7) ,
#P_MOBNO VARCHAR(15) ,
#P_OUT_MSG VARCHAR(2) OUT
)
AS
BEGIN
DECLARE #VOTP INT , #V_LNK INT ,#V_VERAVL VARCHAR(2)
IF #VOTP=0
BEGIN
SELECT #P_OUT_MSG='SUCCESS'
SELECT #P_OUT_MSG
SELECT MCI.CHQ_MIN_LGTH AS MINCHEQUELENGTH,
MCI.VRTL_CARD AS VIRTUALCARD,
FROM TRAN_TABLE MCI WITH(NOLOCK)
WHERE MCI_SOLID=#P_SOLID;
RETURN
END
ELSE
begin
SELECT #P_OUT_MSG='FAILURE'
SELECT #P_OUT_MSG
SELECT MCI.ACCT_STAT AS MINCHEQUELENGTH,
MCI.LOG_ATMPT AS VIRTUALCARD,
FROM TRAN_TABLE MCI WITH(NOLOCK)
WHERE MCI_SOLID=#P_SOLID;
RETURN
end
END
You should have two out argument one for success/failure, and other for the value.
Or you should not have an out argument for success/failure, but RAISE ESCEPTION on failure...

Conversion failed when converting date and/or time from character string - SQL Server 2008 R2

I am busy with a stored procedure to calculate production numbers of shifts. I already have an idea on how to do that but for some kind of strange reason I do not get an insert into with a variable time working. Below is query for the stored procedure:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[ProductionReport]
#filterStartTime datetime,
#filterEndTime datetime,
#machine varchar(10)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
CREATE TABLE #tempProductionTable(
id varchar(3),
ploeg varchar(3),
starttime2 datetime,
endtime2 datetime,
daynumber int)
declare #i int
, #SQLString varchar(400)
, #id varchar(3)
, #ploeg varchar(3)
, #starttime datetime
, #endtime datetime
set #i = 0
while #i < 16
begin
set #i = #i+1
set #id = #i
set #starttime = convert(datetime, #filterStartTime,110)
print #starttime
set #ploeg = '2'
SET #SQLString = 'INSERT INTO #tempProductionTable (id,ploeg,starttime2) values ('+#id+','+#ploeg+','+#starttime+')'
EXEC(#SQLString)
end
-- Insert statements for procedure here
SELECT * from #tempProductionTable
END
And this is the query for opening the stored procedure:
USE [NRPConfiguration]
GO
DECLARE #return_value int
EXEC #return_value = [dbo].[ProductionReport]
#filterStartTime = '2017-01-01 10:00:00.000',
#filterEndTime = N'2-1-2017 0:00',
#machine = N'ASM_008'
SELECT 'Return Value' = #return_value
GO
I already tried a lot of things but still can't get it working. For example when I manually insert a time than it is working. But when I want to do it with an variable it is not working also when I am using the convert function for it. What am I doing wrong?
I use SQL Server 2008 R2 for this.
Quit concatenating strings to executed dynamic sql, use sp_executesql instead.
Your error can be correct by specifying dates in ISO format (or in the format Dan Bracuk mentioned in his comment). e.g. '2017-04-01T23:59:59.363'
#BackToBasics : Dating Responsibly - Aaron Bertrand
Here is how you would use sp_executesql instead:
alter procedure [dbo].[ProductionReport] (
#filterStartTime datetime,
#filterEndTime datetime,
#machine varchar(10)
) as
begin;
-- set nocount on added to prevent extra result sets from
-- interfering with select statements.
set nocount on;
create table #tempProductionTable(
id varchar(3)
, ploeg varchar(3)
, starttime2 datetime
, endtime2 datetime
, daynumber int
);
declare #i int
, #params nvarchar(max)
, #sqlstring nvarchar(max)
, #id varchar(3)
, #ploeg varchar(3)
, #starttime datetime
, #endtime datetime;
set #params = '#id int, #ploeg varchar(3), #starttime datetime';
set #sqlstring = 'insert into #tempProductionTable (id,ploeg,starttime2) values (#id,#ploeg,#starttime);';
set #i = 0
while #i < 16
begin
set #i = #i+1
set #id = #i
set #starttime = convert(datetime, #filterStartTime,110)
set #ploeg = '2'
print #starttime
exec sp_executesql #sqlstring, #params, #id, #ploeg, #starttime;
end
-- Insert statements for procedure here
select * from #tempProductionTable
end;
go
rextester demo: http://rextester.com/KPBR1056

Rewrite Oracle Procedure and trigger for SQL Server

I have an Oracle procedure to add a row to the JOB_HISTORY table and a trigger to call the procedure when data is updated on two columns( job_id, department_id) in the table EMPLOYEES: I´m trying to rewrite them for Sql server 2008, can anyone help me to rewrite both of them please? I might have done it with the procedure but cannot do it with the trigger. any suggestion is welcome?
Procedure:
CREATE OR REPLACE PROCEDURE add_job_history
( p_emp_id job_history.employee_id%type
, p_start_date job_history.start_date%type
, p_end_date job_history.end_date%type
, p_job_id job_history.job_id%type
, p_department_id job_history.department_id%type )
IS BEGIN
INSERT INTO job_history (employee_id, start_date, end_date,job_id,department_id)
VALUES(p_emp_id,p_start_date,p_end_date,p_job_id,p_department_id);
END add_job_history;
Trigger:
CREATE OR REPLACE TRIGGER update_job_history
AFTER UPDATE OF job_id,department_id ON employees
FOR EACH ROW
BEGIN
add_job_history(:old.employee_id, :old.hire_date, sysdate,
:old.job_id,:old.department_id);
END;
This is how I wrote the procedure I´m not sure is doing the same thing as the one above though.
CREATE PROCEDURE add_job_history
(#p_emp_id INTEGER,
#p_start_date DATE,
#p_end_date DATE,
#p_job_id VARCHAR(10),
#p_department_id INTEGER ) AS
BEGIN
INSERT INTO job_history (employee_id, start_date, end_date,
job_id, department_id)
VALUES(#p_emp_id, #p_start_date, #p_end_date, #p_job_id,#p_department_id)
END ;
CREATE TRIGGER update_job_history ON (table_EMPLOYEES)
AFTER UPDATE
AS
BEGIN
if exists(select 1 From inserted as i inner join deleted as d on d.employee_id = i.employee_id where d.job_id != i.job_id or d.department_id != i.department_id)
begin
insert into job_history (employee_id, start_date, end_date,job_id,department_id)
select d.employee_id, d.start_date,d.end_date,d.job_id,d.department_id
from deleted as d
end
END;
thanks for your help #Long
I found The answer even if I still have to test the logic of it and i might change some inserted i. with d.
create trigger update_job_history on employees
after update
as
begin
set nocount on;
insert into job_history (employee_id, start_date, end_date ,job_id,department_id)
select i.employee_id, i.hire_date as start_date , d.hire_date as end_date, d.job_id ,d.department_id
From inserted as i inner join deleted as d on d.employee_id = i.employee_id where d.job_id != i.job_id or d.department_id != i.department_id
end

ColdFusion CFQuery block as per postgres

I have not been able to get this code block to run my query against postgres in CFQuery of ColdFusion:
<cfquery name="uiCustomColumn" datasource="#arguments.dsn#">
DECLARE resultValue int;
DECLARE nextId bigint;
BEGIN
IF (( select count( udc_id ) from user_defined_column WHERE udc_is_active = true ) >= 10) THEN
INSERT INTO user_defined_column(udc_id)
VALUES(<cfqueryparam value="#this.getLabel()#" cfsqltype="cf_sql_varchar" maxlength="25">)
END IF;
END;
</cfquery>
What you have there is plpgsql syntax (the default PostgreSQL procedural language), not SQL.
You'd need to wrap this in a DO command or CREATE FUNCTION with it.
Or rewrite it with SQL syntax. Something along these lines:
INSERT INTO user_defined_column(udc_id)
SELECT <this.getLabel()>
WHERE (
SELECT count(udc_id) > 9
FROM user_defined_column
WHERE udc_is_active
)

Getting Top N from stored procedure

I have a stored procedure that cannot be modified, I'm going to stress this before anyone suggests I re-write the stored procedure or add the query from inside the stored procedure into a function.
The procedure lives on another database that we have very limited access to; so what I want to do is somehow wrap the stored procedure in a query, function or stored procedure that will allow me to select the top N rows from the returned data.
Ideally I would be able to call something like...
DECLARE #ForeName varchar(50)
DECLARE #Surname varchar(50)
DECLARE #DOB datetime
DECLARE #Sex varchar(1)
SET #Surname = 'Smith'
SELECT TOP 10 (
EXECUTE #RC = [Some_Other_Database].[dbo].[sp_search_demographics]
,#ForeName
,#Surname
,#DOB
,#Sex
)
GO
edit: (I should also note that the stored procedure returns a parameter containing the row count as well as the rows)
edit2: I should also note that I'm using MS SQL Server 2008 R2
I'm aware that this is in no way correct, is there any way to do something like this? at the moment for vague queries we are getting thousands of rows returned; which is slowing the server considerably.
I have done some Googling and stack-overflowing for a solution but unfortunately all the advice I could find involved modifying the stored procedure.
Look up EXEC SP_EXECUTESQL(#SQL)
However the problem will be that the called sp will still return all the rows, so you may not get the improvement in performance you are looking for.
You can also set the number of rows returned by a query - but depends on your access level
http://blog.sqlauthority.com/2007/04/30/sql-server-set-rowcount-retrieving-or-limiting-the-first-n-records-from-a-sql-query/
Hope this helps
Declare #i Numeric(18,2)
Declare #strSQL nvarchar(1000)
select #i = Round(COUNT(1)/10,2) from tb_Item
print(#i)
Declare #j int = 0
Declare #rem numeric(18,2)
select #rem = COUNT(1) - ((COUNT(1)/10) * 10) from tb_Item
while #i > 0
Begin
set #j = (#j + 1);
if #j = 1
Begin
WITH OrderedOrders AS
(
select
ROW_NUMBER() over(order by ItemID) AS RowNumber
,ItemName
from tb_Item
)
SELECT ItemName, RowNumber
FROM OrderedOrders
WHERE RowNumber BETWEEN (#j*10)-10 AND #j*10;
End
Else
Begin
WITH OrderedOrders AS
(
select
ROW_NUMBER() over(order by ItemID) AS RowNumber
,ItemName
from tb_Item
)
SELECT ItemName, RowNumber
FROM OrderedOrders
WHERE RowNumber BETWEEN ((#j*10)-10) + 1 AND #j*10;
End
set #i = #i - 1;
end;
WITH OrderedOrders AS
(
select
ROW_NUMBER() over(order by ItemID) AS RowNumber
,ItemName
from tb_Item
)
SELECT ItemName, RowNumber
FROM OrderedOrders
WHERE RowNumber BETWEEN (#j*10)+1 and (#j*10) + #rem ;