I would like to know how to resolve this syntax error. I've tried lots of ways, however, when I try to compile my function a message SQL 42601 is displayed.
The code that I use:
create or replace PROCEDURE SP_Generate_EventToken(EventId bigint) AS $$
DECLARE TokenCount int;
DECLARE Success int;
DECLARE SerialNo int=0;
BEGIN
BEGIN TRY
SET #Success = 0;
--Get Available Token count
SELECT #TCNT = COUNT(Field1) FROM TbECT WHERE Field2 = 0;
IF EventId > 0
BEGIN
SELECT SerialNo=(SerialNo) from TbDefault
--Get Generated Token Count
SELECT #TokenCount = COUNT(Id) FROM TbComplementaryClaim WHERE [EventId] = EventId
--Get Guest Count
SELECT #GUESTNO = (CASE WHEN TokenType = 0 THEN [NoOfGuests] WHEN TokenType = 1 THEN 1 WHEN TokenType = 2 THEN [NoOfGuests] END), #TokenType = TokenType, #GUESTNOC = [NoOfGuests] FROM [dbo].[TbComplementaryEvents] WHERE [Id] = #EventId
SET #GUESTNO = #GUESTNO - #TokenCount
IF #GUESTNO > 0
BEGIN
BEGIN TRANSACTION
--Reset all token
IF #TCNT < #GUESTNO
BEGIN
UPDATE TbECT SET Field2 = 0
END
COMMIT TRANSACTION
END
END
END TRY
END;
$$ LANGUAGE plpgsql;
Error message I receive:
ERROR: syntax error at or near "TRY"
LINE 14: BEGIN TRY;
^
SQL state: 42601
Character: 316
What is wrong? How can I solve this problem?
Related
This is a working function in SQL Server 2014 Express
CREATE FUNCTION [dbo].[Func_Account_FollowingCustomer]
(#AccountNumber NVARCHAR(20))
RETURNS BIT
AS
BEGIN
DECLARE #bResult BIT
IF (SELECT COUNT(AccountNumber) FROM dbo.Account AS A
WHERE DetailByAccountObject = 1
AND AccountObjectType = 1
AND AccountNumber = #AccountNumber) > 0
SET #bResult = 1
ELSE
SET #bResult = 0
RETURN #bResult
END
I try to convert to PostgreSQL 14, I have
CREATE FUNCTION public.func_account_following_customer(IN account_number character varying)
RETURNS bit
LANGUAGE 'sql'
declare #b_result bit
begin
if(select count(account_number) from account as a where detail_by_account_object = 1 and account_object_type = 1 and account_number = #account_number) > 0
set #b_result = 1
else
set #b_result = 0
return #b_result;
end;
ALTER FUNCTION public.func_account_following_customer(character varying)
OWNER TO postgres;
Error
ERROR: syntax error at or near "declare" LINE 5: declare #b_result bit ^
How to fix it?
language sql can't use variables or procedural elements (like IF), you need language plpgsql - but the syntax for variable names is different and the assignment is not done using set
The function body is a string constant, typically specified using dollar quoting.
If you want to return true/false flags, use boolean instead of bits.
Parameters or variables are referenced using # but simply with their name.
But you don't need procedural code for such a simple SQL query that just returns true/false.
CREATE FUNCTION public.func_account_following_customer(IN p_account_number character varying)
RETURNS boolean
LANGUAGE sql
as
$$
select count(*) > 0
from account as a
where detail_by_account_object = 1
and account_object_type = 1
and account_number = p_account_number;
$$
;
As a PL/pgSQL function this would be:
CREATE FUNCTION public.func_account_following_customer(IN p_account_number character varying)
RETURNS boolean
LANGUAGE plpgsql
as
$$
declare
l_result boolean;
begin
if (select count(*)
from account as a
where detail_by_account_object = 1
and account_object_type = 1
and account_number = p_account_number) > 0
then
l_result := true;
else
l_result := false;
end if;
return l_result;
end;
$$
;
I am creating a user defined function in PostgreSQL and facing error.
Also, please suggest a better way (if any) to execute this function.
CREATE FUNCTION public.mark_enrollment_completed(IN enrollment_id text)
RETURNS boolean
LANGUAGE plpgsql
AS $BODY$
DECLARE
total_contents INTEGER;
completed_content_count INTEGER;
user_id TEXT;
course_id TEXT;
was_marked BOOLEAN;
BEGIN
SELECT user_id, course_id INTO user_id, course_id FROM enrollments WHERE enrollment_id = enrollment_id;
SELECT count(*) INTO total_contents FROM course_contents WHERE course_id = course_id;
SELECT count(*) INTO completed_content_count FROM completed_contents WHERE user_id = user_id;
IF total_contents = completed_content_count THEN
UPDATE enrollments SET is_completed = true WHERE enrollment_id = enrollment_id;
SET was_marked = true;
ELSE
SET was_marked = false;
RETURN was_marked;
END;
$BODY$;
Error:
ERROR: syntax error at or near ";"
LINE 22: END;
^
SQL state: 42601
Character: 750
As documented in the manual assignment is done using := operator - there is no SET in PL/pgSQL.
You are also missing the END IF
IF total_contents = completed_content_count THEN
UPDATE enrollments SET is_completed = true WHERE enrollment_id = enrollment_id;
was_marked := true;
ELSE
was_marked := false;
END IF;
RETURN was_marked;
Updating my TFS 2013 Update 4 collection to TFS 2015 Update 3. Using a backup of the production collection data in a DEV location. Did the backup with the production collection being detached. Didn't have any errors. The backup is 254GB.
This is the error currently stopping me from attaching the collection:
Msg 3732, Level 16, State 1, Line 93
Cannot drop type 'typ_ItemSpec2' because it is being referenced by object 'prc_QueryPendingChanges_MS'. There may be other objects that reference this type.
SET XACT_ABORT ON
SET NOCOUNT ON
DECLARE #status INT
DECLARE #procedureName SYSNAME = N'upd_VersionControlToDev14M80_PostSchema'
DECLARE #tfError NVARCHAR(255)
IF EXISTS (
SELECT *
FROM sys.triggers
WHERE name = 'trg_tbl_VCFirstRunProject'
)
BEGIN
DROP TRIGGER trg_tbl_VCFirstRunProject
END
IF EXISTS (
SELECT *
FROM sys.indexes
WHERE name = 'IX_tbl_VCFirstRunProject_OldServerItemPrefix'
AND object_id = OBJECT_ID('dbo.tbl_VCFirstRunProject')
)
BEGIN
-- Delete upgrade-only rows for $\, a few partitions at a time
-- We need dynamic SQL for this to be rerunnable.
EXEC #status = sp_executesql N'
DECLARE #batchStart INT = 1
DECLARE #batchEnd INT
DECLARE #end INT
DECLARE #batchSize INT = 50
-- Get the partition range
SELECT TOP (1)
#end = PartitionId
FROM tbl_VCFirstRunProject
ORDER BY PartitionId DESC
WHILE (#batchStart <= #end)
BEGIN
SET #batchEnd = #batchStart + #batchSize
DELETE tbl_VCFirstRunProject
WHERE PartitionId BETWEEN #batchStart AND #batchEnd
AND OldServerItemPrefix = N''''
OPTION (OPTIMIZE FOR (#batchStart=1, #batchEnd=50))
SET #batchStart = #batchEnd + 1
END
'
IF (#status <> 0)
BEGIN
SET #tfError = dbo.func_GetMessage(500004); RAISERROR(#tfError, 16, -1, #procedureName, #status, N'sp_executesql', N'DELETE tbl_VCFirstRunProject')
RETURN
END
DROP INDEX IX_tbl_VCFirstRunProject_OldServerItemPrefix ON tbl_VCFirstRunProject
END
IF EXISTS (
SELECT *
FROM sys.columns
WHERE object_id = Object_ID(N'dbo.tbl_VCFirstRunProject', N'U')
AND name = N'OldServerItemPrefix'
)
BEGIN
ALTER TABLE tbl_VCFirstRunProject
DROP COLUMN OldServerItemPrefix, NewServerItemPrefix
END
IF TYPE_ID('dbo.typ_BranchObject2') IS NOT NULL
BEGIN
DROP TYPE typ_BranchObject2
END
IF TYPE_ID('dbo.typ_BuildMappingInput2') IS NOT NULL
BEGIN
DROP TYPE typ_BuildMappingInput2
END
IF TYPE_ID('dbo.typ_CreateLabelInput') IS NOT NULL
BEGIN
DROP TYPE typ_CreateLabelInput
END
IF TYPE_ID('dbo.typ_ExpandedChange2') IS NOT NULL
BEGIN
DROP TYPE typ_ExpandedChange2
END
IF TYPE_ID('dbo.typ_ItemSpec2') IS NOT NULL
BEGIN
DROP TYPE typ_ItemSpec2
END
IF TYPE_ID('dbo.typ_LocalPendingChange3') IS NOT NULL
BEGIN
DROP TYPE typ_LocalPendingChange3
END
IF TYPE_ID('dbo.typ_LocalVersion3') IS NOT NULL
BEGIN
DROP TYPE typ_LocalVersion3
END
IF TYPE_ID('dbo.typ_LockConflictCandidate2') IS NOT NULL
BEGIN
DROP TYPE typ_LockConflictCandidate2
END
IF TYPE_ID('dbo.typ_LockObject') IS NOT NULL
BEGIN
DROP TYPE typ_LockObject
END
IF TYPE_ID('dbo.typ_Mapping2') IS NOT NULL
BEGIN
DROP TYPE typ_Mapping2
END
IF TYPE_ID('dbo.typ_PendingAdd2') IS NOT NULL
BEGIN
DROP TYPE typ_PendingAdd2
END
IF TYPE_ID('dbo.typ_PendingChangeObject') IS NOT NULL
BEGIN
DROP TYPE typ_PendingChangeObject
END
IF TYPE_ID('dbo.typ_PendingChangeSecurity') IS NOT NULL
BEGIN
DROP TYPE typ_PendingChangeSecurity
END
IF TYPE_ID('dbo.typ_PendingMerge2') IS NOT NULL
BEGIN
DROP TYPE typ_PendingMerge2
END
IF TYPE_ID('dbo.typ_PendingPropertyChange2') IS NOT NULL
BEGIN
DROP TYPE typ_PendingPropertyChange2
END
IF TYPE_ID('dbo.typ_VersionedItemId') IS NOT NULL
BEGIN
DROP TYPE typ_VersionedItemId
END
None of the standard queries from Microsoft have _MS as a suffix. I suspect that someone hand-tweaked the original prc_QueryPendingChanges and left this around as a backup. In that case you should be able to drop this procedure and retry the upgrade.
I have created a procedure in Sybase
create procedure prcrms_crms_cust_id_verify_ins(#customer_code numeric(12,0),#id_type tinyint,#verification_status varchar(12),#verification_response varchar(255),#verification_date datetime,#add_user varchar(21)) as
begin
declare #check_id_exists int
select #check_id_exists = count(*) from crms_customer_id_verification where ( ('customer_code'=#customer_code) and ('id_type'=#id_type))
if(#check_id_exists > 0)
begin
update crms_customer_id_verification set verification_status=#verification_status,verification_response=#verification_response,verification_date=#verification_date where ( ('customer_code'=#customer_code) and ('id_type'=#id_type))
return ##rowcount
end
if((#check_id_exists <> null) or (#check_id_exists <> 0))
begin
insert into crms_customer_id_verification(customer_code,id_type,verification_status,verification_response,verification_date,add_user) values(#customer_code,#id_type,#verification_status,#verification_response,#verification_date,#add_user)
return ##rowcount
end
end
when i try to execute the procedure
exec prcrms_crms_cust_id_verify_ins(3344,0,"VERIFIED",'{test:test}','1998-09-09 12:12:12.000','Admin')
it shows Incorrect syntax near '3344'.
/*
create procedure prcrms_crms_cust_verify_ins(#customer_code varchar(255),#id_type varchar(255) ,#verification_status varchar(12),#verification_response varchar(255),#verification_date varchar(255),#add_user varchar(21))as
/*
** ------------------------------------
** Created By : Bibil Mathew Chacko
** Created On : Jul 16 2016
** Description : insert in crms_customer_id_verification if id_type and customer exist.Update table if customer and id_type exist.
** -------------------------------------
*/
begin
declare
#check_id_exists int,
#cc numeric,
#id_t tinyint,
#vd datetime
select #cc = convert(numeric(12,0),#customer_code)
select #id_t = convert(tinyint,#id_type)
select #vd = convert(datetime,#verification_date)
select #check_id_exists = count(*) from crms_customer_id_verification where ( (customer_code=#cc) and (id_type=#id_t))
if(#check_id_exists > 0)
begin
update crms_customer_id_verification set verification_status=#verification_status,verification_response=#verification_response,verification_date=#vd where (customer_code=#cc and id_type=#id_t)
return ##rowcount
end
if((#check_id_exists <> null) or (#check_id_exists <> 0))
begin
insert into crms_customer_id_verification(customer_code,id_type,verification_status,verification_response,verification_date,add_user) values(#cc,#id_t,#verification_status,#verification_response,#vd,#add_user)
return ##rowcount
end
end
*/
/*exec prcrms_crms_cust_verify_ins '3344','0',"VERIFIED",'{test:test}','1998-09-09 12:12:12.000','Admin'*/
Should use VARCHAR type as parameter and procedure should have support for converting to required type. Another mistake I have done is Sybase Procedures don't have parenthesis.
I have the following procedure which is supposed to insert a cell in a many to many table. The problem it it fails, with an error message which I do not get where it is caused, since I do not intend to do any conversion.
ALTER PROCEDURE [dbo].[updateGrade]
#grade int,
#studentName nvarchar(50),
#courseName nvarchar(50)
AS
BEGIN TRANSACTION;
BEGIN TRY
IF (#grade < 0 OR #grade > 10 OR #grade=NULL )
RAISERROR('!! grade -- #grade < 0 OR #grade > 10 OR ISNULL(#grade, 0) = 0', 18, 0)
IF (#studentName = '' OR ISNULL(#studentName,0) = 0)
RAISERROR('!! studentName -- #studentName = '' OR ISNULL(#studentName)', 18, 0)
IF (#courseName = '' OR ISNULL(#courseName,0) = 0)
RAISERROR('!! courseName -- #courseName = '' OR ISNULL(#studentName)', 18, 0)
SET #studID = (SELECT id FROM students WHERE students.name = #studentName)
SET #courseID = (SELECT id FROM courses WHERE courses.name = #courseName)
INSERT INTO grades (grade, studentID, courseID)
VALUES (#grade, #studID, #courseID)
END TRY
BEGIN CATCH
SELECT
ERROR_NUMBER() AS ErrorNumber
,ERROR_SEVERITY() AS ErrorSeverity
,ERROR_STATE() AS ErrorState
,ERROR_PROCEDURE() AS ErrorProcedure
,ERROR_LINE() AS ErrorLine
,ERROR_MESSAGE() AS ErrorMessage;
IF ##TRANCOUNT > 0
ROLLBACK TRANSACTION;
END CATCH;
IF ##TRANCOUNT > 0
COMMIT TRANSACTION;
params:
params: 6 / Maier Bogdan / baze2
ret code:
DECLARE #return_value int
EXEC #return_value = [dbo].[updateGrade]
#grade = 6,
#studentName = N'Maier Bogdan',
#courseName = N'baze2'
SELECT 'Return Value' = #return_value
GO
Error:
Conversion failed when converting the nvarchar value 'Maier Bogdan' to data type int.
Error is here:
ISNULL(#studentName,0) = 0
Comparing #studentName (nvarchar(50)) to 0 (int)
Notice that when #studentName is Null the problem not appear because you compare 0 to 0, but, when #studentName is not null you are comparing #studentName to 0!