what am I doing wrong w/ this SQL? - sql

When I run this it doesn't throw an error however it doesn't insert/delete an entry either. I don't know why it's not working.
DECLARE #trAction VARCHAR(5)
SET #trAction = 'addTR'
IF EXISTS (SELECT TransgeneID
FROM tbl_MT
WHERE MouseID = '3' AND TransgeneID = '3')
IF (#trAction = 'rmvTR')
DELETE
FROM tbl_MT
WHERE MouseID = '3' AND TransgeneID = '3'
ELSE
IF (#trAction = 'addTR')
INSERT INTO tbl_MT
VALUES ('3', '3')

First, put BEGIN and END on the IF's:
DECLARE #trAction VARCHAR(5)
SET #trAction = 'addTR'
IF EXISTS (SELECT TransgeneID
FROM tbl_MT
WHERE MouseID = '3' AND TransgeneID = '3')
BEGIN
IF (#trAction = 'rmvTR')
BEGIN
DELETE
FROM tbl_MT
WHERE MouseID = '3' AND TransgeneID = '3'
END
END
ELSE
BEGIN
IF (#trAction = 'addTR')
BEGIN
INSERT INTO tbl_MT
VALUES ('3', '3')
END
END
Second and final, if the first IF is true, the inner IF (#trAction = 'rmvTR') will fail and nothing will be done.

Related

SQL 2008 user defined function not recognized

This is my first attempt at a user defined function so I am having some issues identifying what I am doing incorrectly. My goal is to create a function that will accept a part id as a paramater and then processes a series of if conditions that analyze the second character in the ID to determine product type based on standard naming conventions. I have made a few tweaks in the script, I have ran each version in master as well as the database. I have not received any failure errors when creating the function however each attempt at using it results in the following error. 'get_product_type' is not a recognized built-in function name.
Current version of this function is bellow.
create function get_product_type (#part nvarchar(30))
returns nvarchar(30)
with execute as caller
as
begin
DECLARE #product nvarchar(30);
if SUBSTRING(#part,1,1) = 'A'
set #product = 'ELLIPTICAL';
else if SUBSTRING(#part,1,1) = 'B'
set #product = 'F&D SPHERICAL';
else if SUBSTRING(#part,1,1) = 'C'
set #product = 'F&D SPHERICAL';
else if SUBSTRING(#part,1,1) = 'D'
set #product = 'HEMISPHERICAL';
else if SUBSTRING(#part,1,1) = 'E'
set #product = 'CONICAL';
else if SUBSTRING(#part,1,1) = 'F'
set #product = 'FLANGED ONLY';
else if SUBSTRING(#part,1,1) = 'G'
set #product = 'DISHED ONLY';
else if SUBSTRING(#part,1,1) = 'H'
set #product = 'TULIP BOWL';
else if SUBSTRING(#part,1,1) = 'I'
set #product = 'TESTING/COUPONS/CHARPIES';
else if SUBSTRING(#part,1,1) = 'J'
set #product = 'FLARED/DISHED';
else if SUBSTRING(#part,1,1) = 'K'
set #product = 'HEAD BRACES';
else if SUBSTRING(#part,1,1) = 'L'
set #product = 'MISCELLANEOUS';
else if SUBSTRING(#part,1,1) = 'M'
set #product = 'HEAD PAD EXTENSIONS';
else if SUBSTRING(#part,1,1) = 'N'
set #product = 'HEAD PADS';
else if SUBSTRING(#part,1,1) = 'O'
set #product = 'MISCELLANEOUS';
else if SUBSTRING(#part,1,1) = 'P'
set #product = 'HUBS';
else if SUBSTRING(#part,1,1) = 'Q'
set #product = 'FLANGED/FLUED';
else if SUBSTRING(#part,1,1) = 'R'
set #product = 'FLUED/PLATE';
else if SUBSTRING(#part,1,1) = 'S'
set #product = 'SILL PAD';
else if SUBSTRING(#part,1,1) = 'T'
set #product = 'TOOLING';
else if SUBSTRING(#part,1,1) = 'U'
set #product = 'CYLENDAR REPAD';
else if SUBSTRING(#part,1,1) = 'V'
set #product = 'ROLLING CANS';
else if SUBSTRING(#part,1,1) = 'W'
set #product = 'HEAT TREAT';
else if SUBSTRING(#part,1,1) = 'X'
set #product = 'SPHERE';
else if SUBSTRING(#part,1,1) = 'Y'
set #product = 'BLASTING';
else if SUBSTRING(#part,1,1) = 'Z'
set #product = 'MISCELLANEOUS';
else set #product = 'MISCELLANEOUS';
return #product
end
If the issue is in how I have been trying to call the function, all of my attempst have been,
get_product_type(cl.PART_ID),
If anyone can provide a push in the right direction it will be greatly appreciated.
Thanks everyone.
I wouldn't do it like this -- it is very slow and you can use SQL to make this process fast using a left join
First define a table with two columns, a one character code and a description
It would look something like this
CREATE TABLE LOOKUP (
CODE CHAR(1),
DESC VARCHAR(100)
)
Make the CODE field the primary key.
Then you can "call" your function like this:
SELECT
COALESCE(LOOKUP.DESC,'MISCELLANEOUS') AS DESC
FROM TABLENAMEHERE
LEFT JOIN LOOKUP ON LOOKUP.CODE = SUBSTRING(TABLENAMEHERE.PRODUCTCODE,1,1)

SQL Server condition not working

Below is part of a SQL Server query which is not working as expected. I don't know why, but condition falls through this part, like nothing is inserted (like all three conditions are set to NULL). What am I doing wrong here?
Input parameters for the stored procedure:
#cStockPacked varchar(1) = NULL,
#cWrittenDown varchar(1) = NULL,
#cInPreparation varchar(1) = NULL
Part of the query which is not working:
(
(#cStockPacked IS NULL OR
(#cStockPacked = '1' AND MEST.MEST_STA = '1')
)
OR
(#cInPreparation IS NULL OR
(#cInPreparation = '1' AND MEST.MEST_STA = '2')
)
OR
(#cWrittenDown IS NULL OR
(#cWrittenDown = '1' AND MEST.MEST_STA = '4')
)
)
I've tried to hard code conditions, everything worked as expected:
(
MEST.MEST_STA = '1' OR MEST.MEST_STA = '2' OR MEST.MEST_STA = '4'
)
I've tried with one condition (hardcoded), then with two and later with all three. All was good. I want to achieve the same result with query pasted above, but something is obviously wrong. What am I doing wrong?
Whole procedure:
ALTER PROCEDURE [dbo].[sp_CAMERC_HLP]
( , #cStockPacked varchar(1) = NULL
, #cWrittenDown varchar(1) = NULL
, #cInPreparation varchar(1) = NULL
)
AS
BEGIN
SELECT
MEST.MEST_QUA, MERC_STA, MERC_NME,
MERC_DES, MERC_NTO, MERC_UNI, MERC_LPR,
MERC.UNIT_KEY,
COUNT_ALL_ROWS = COUNT(*) OVER()
FROM
CAMERC MERC
INNER JOIN
CAMEGR CAMEGR ON MERC.MEGR_KEY = CAMEGR.MEGR_KEY
INNER JOIN
CAMEST MEST ON MERC.MERC_KEY = MEST.MERC_KEY
WHERE
(#cMERC_NME IS NULL OR MERC_NME LIKE '%' + #cMERC_NME + '%')
AND
(#iMEGR_KEY IS NULL OR MERC.MEGR_KEY IN (SELECT MEGR_KEY FROM CTE))
AND
(#cMERC_CDO1 IS NULL OR MERC_CDO1 LIKE '%' + #cMERC_CDO1 + '%')
AND
and
(
(#cStockPacked IS NULL OR #cStockPacked = '1' AND MEST.MEST_STA = '1')
OR
(#cInPreparation IS NULL OR (#cInPreparation = '1' AND MEST.MEST_STA = '2'))
OR
(#cWrittenDown IS NULL OR (#cWrittenDown = '1' AND MEST.MEST_STA = '4'))
)
END
You may looking for this
(
(
(#cStockPacked IS NOT NULL AND #cStockPacked = '1' AND MEST.MEST_STA = '1') OR
(#cInPreparation IS NOT NULL AND #cInPreparation = '1' AND MEST.MEST_STA = '2') OR
(#cWrittenDown IS NOT NULL AND #cWrittenDown = '1' AND MEST.MEST_STA = '4')
)
OR
( #cStockPacked IS NULL OR #cInPreparation IS NULL OR #cWrittenDown IS NULL )
)
I don't understand why you accepted that answer as correct, it does not make much sense to test var for NULL with those conditions.
All you need - to make these conditions same as others. Just like this:
AND (#cMERC_NME IS NULL OR MERC_NME LIKE '%' + #cMERC_NME + '%')
update them to:
AND (#cStockPacked IS NULL OR (#cStockPacked = '1' AND MEST.MEST_STA = '1'))
AND (#cInPreparation IS NULL OR (#cInPreparation = '1' AND MEST.MEST_STA = '2'))
AND (#cWrittenDown IS NULL OR (#cWrittenDown = '1' AND MEST.MEST_STA = '4'))
that's it.

IF condition in trigger in SQL Server

I converting this Oracle trigger to SQL Server. In Oracle there are using if condition for updating a table. I was wondering is it necessary to use if statement in SQL Server. I'm thinking to use in where clause. Please let me know if that's correct?
Thanks
CREATE OR REPLACE TRIGGER "DB1"."TG_PG_CODES"
BEFORE UPDATE OF "str_number", "op_status"
ON "DB1"."Header_T"
REFERENCING OLD AS oldrow NEW AS newrow
FOR EACH ROW
BEGIN
IF :newrow.op_status = 'X'
THEN
UPDATE DB1.pg_pollutant
SET op_status = 'X',
str_comp_status = '98',
str_mod_person = '3327'
WHERE str_number = :newrow.str_number;
END IF;
IF :newrow.op_status <> 'X'
AND SUBSTR (:oldrow.str_pgcodes, 1, 1) = '1'
AND SUBSTR (:newrow.str_pgcodes, 1, 1) = '0'
THEN
UPDATE DB1.pg_pollutant
SET op_status = 'X',
str_comp_status = '98'
WHERE str_number = :newrow.str_number
AND str_pollutant_key = :newrow.str_number || '0';
END IF;
END;
=============================================
In sql server
CREATE TRIGGER [dbo].[TG_TG_PG_CODES] ON [dbo].[Header_T]
AFTER UPDATE
AS
IF(UPDATE(str_number)
OR UPDATE(op_status))
BEGIN
IF(
(
SELECT op_status
FROM inserted
) = 'X')
BEGIN
UPDATE a
SET
a.op_status = 'X',
a.str_comp_status = '98',
a.str_mod_person = '3327'
FROM DB1.pg_pollutant a
INNER JOIN inserted AS i ON a.str_number = i.str_number;
END;
UPDATE a
SET
a.op_status = 'X',
a.str_comp_status = '98'
FROM DB1.pg_pollutant a
INNER JOIN inserted AS i ON a.[str_number] = i.[str_number]
AND a.str_pollutant_key = i.[str_number]+'0'
INNER JOIN Deleted AS d ON a.[str_number] = d.[str_number]
WHERE i.stroperationalstatus <> 'X'
AND SUBSTRING(d.str_pgcodes, 1, 1) = '1'
AND SUBSTRING(i.str_pgcodes, 1, 1) = '0'; /* I used this condition in where clause */
END;

how to set default value in a output parameter

in my following query i want to set 0, 0, 0 in #TMarks, #OMarks, #Percentage respectively if the select statement used with them returns nothing
create procedure [dbo].[TestRecordSelectMInfo]
#GRNo varchar(4),
#SessionId numeric(1),
#TestTypeId numeric(1),
#TMarks int output,
#OMarks numeric(4) output,
#Percentage numeric(4) output,
#Grade varchar(4) output
as
begin
SELECT Subjects.Subject, Marks.TotalMarks, Marks.PassingMarks, TestRecord.Marks, Result = case when TestRecord.Marks = 'A' then 'A' else case when cast(TestRecord.Marks as numeric) < Marks.PassingMarks then 'F' else 'P' end end FROM Subjects INNER JOIN Marks ON Subjects.SubjectId = Marks.SubjectId INNER JOIN TestRecord ON Subjects.SubjectId = TestRecord.SubjectId AND Marks.TestTypeId = TestRecord.TestTypeId where TestRecord.SessionId = #SessionId and TestRecord.TestTypeId = #TestTypeId and TestRecord.GRNo = #GRno
set #TMarks = (select sum(Marks.TotalMarks) from Marks inner join TestRecord on Marks.TestTypeId = TestRecord.TestTypeId and Marks.SubjectId = TestRecord.SubjectId where TestRecord.SessionId = #SessionId and TestRecord.TestTypeId = #TestTypeId and TestRecord.GRNo = #GRNo and TestRecord.Marks <> 'A' and cast(TestRecord.Marks as numeric) > Marks.PassingMarks )
set #OMarks = (select sum(cast(TestRecord.Marks as numeric)) from Marks inner join TestRecord on Marks.TestTypeId = TestRecord.TestTypeId and Marks.SubjectId = TestRecord.SubjectId where TestRecord.SessionId = #SessionId and TestRecord.TestTypeId = #TestTypeId and TestRecord.GRNo = #GRNo and TestRecord.Marks <> 'A' and cast(TestRecord.Marks as numeric) > Marks.PassingMarks)
set #Percentage = #OMarks / #TMarks * 100;
set #Grade = case
when #Percentage < 50
then
'NIL'
else
case
when #Percentage < 60
then
'C'
else
case
when #Percentage < 70
then
'B'
else
case
when #Percentage < 80
then
'A'
else
case
when #Percentage <= 100
then
'A+'
else
'FAIL'
end
end
end
end
end
end
GO
EDIT: An aggregate without a group by returns null for an empty set. You could work around this with insull:
select #TMarks = IsNull(sum(Marks.TotalMarks),0)
from Marks
inner join TestRecord
on Marks.TestTypeId = TestRecord.TestTypeId
and Marks.SubjectId = TestRecord.SubjectId
where TestRecord.SessionId = #SessionId
and TestRecord.TestTypeId = #TestTypeId
and TestRecord.GRNo = #GRNo
and TestRecord.Marks <> 'A'
and cast(TestRecord.Marks as numeric) > Marks.PassingMarks

FireBird: How do you nest a select in an if?

I'm very new to FireBird, but I want to know how I can use a select statement as part of my conditional criteria. I feel like I've been to the internet in back trying to find a way to do this, but haven't come up with much. Below is my attempt at getting this to work. Thanks in advance for any help.
SET TERM ^ ;
ALTER PROCEDURE sp_test (
IPADD Varchar(32),
HN Varchar(32),
NOTE Varchar(200) )
RETURNS ( update_count integer )
AS
BEGIN
IF((SELECT COUNT(*)
FROM ADDRESSES a
WHERE a.ADDRESS_TYPE = 'Reserved'
AND a.ALIVE = 'N'
AND (a.HOST_NAME = '' OR a.HOST_NAME is NULL)
AND (a.DNS_NAME = '' OR a.DNS_NAME is NULL)
AND (a.SYSTEM_NAME = '' OR a.SYSTEM_NAME is NULL)) > 0)
THEN
UPDATE
ADDRESSES a
SET
a.HOST_NAME = :HN,
a.ADDRESS_TYPE = 'Assigned',
a.NOTES = :NOTE
WHERE
a.SHORT_IP_ADDRESS = :IPADD;
update_count = 1;
SUSPEND;
ELSE
update_count = 0;
SUSPEND;
END^
SET TERM ; ^
GRANT EXECUTE
ON PROCEDURE sp_test TO SYSDBA;
Using COUNT to check is there records to update is not the best way, use EXISTS instead, ie your IF would be
IF(EXISTS(SELECT 1 FROM ADDRESSES a
WHERE a.ADDRESS_TYPE = 'Reserved'
AND a.ALIVE = 'N'
AND (a.HOST_NAME = '' OR a.HOST_NAME is NULL)
AND (a.DNS_NAME = '' OR a.DNS_NAME is NULL)
AND (a.SYSTEM_NAME = '' OR a.SYSTEM_NAME is NULL)))
THEN
But there seems to be a problem with your return value, update_count - you return 1 if you execute the UPDATE, but the actual number of rows affected by the statement might be something else. I suggest you use ROW_COUNT context variable instead. So your procedure would be
ALTER PROCEDURE sp_test (
IPADD Varchar(32),
HN Varchar(32),
NOTE Varchar(200) )
RETURNS ( update_count integer )
AS
BEGIN
IF(EXISTS(SELECT 1 FROM ADDRESSES a
WHERE (a.ADDRESS_TYPE = 'Reserved')
AND (a.ALIVE = 'N')
AND (a.HOST_NAME = '' OR a.HOST_NAME is NULL)
AND (a.DNS_NAME = '' OR a.DNS_NAME is NULL)
AND (a.SYSTEM_NAME = '' OR a.SYSTEM_NAME is NULL)))
THEN BEGIN
UPDATE ADDRESSES a SET
a.HOST_NAME = :HN,
a.ADDRESS_TYPE = 'Assigned',
a.NOTES = :NOTE
WHERE a.SHORT_IP_ADDRESS = :IPADD;
update_count = ROW_COUNT;
END ELSE update_count = 0;
SUSPEND;
END^