SQL 2008 user defined function not recognized - sql

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)

Related

Search filter on two fields based upon condition

Here is my table
create table Table1 (Id int, ...some fields... , CategoryId int, ProfileId int)
I want to write a SP(stored procedure) which will give me search results from the table based upon the parameters passed to the SP. Here is my procedure
Create proc Search
(
#MediaType1 varchar(1000),
#MediaType2 varchar(1000),
#MediaType3 varchar(1000)
)
as
begin
select * from table
where
case when #MediaType1 = '' then 1 else CategoryId end in
(select case when #MediaType1 = '' then 1 else Splvalue end
from dbo.Split(case #MediaType1 when '0,' then '1,2,3,4' when '' then '1,' else #MediaType1 end,','))
and
case when #MediaType2 = '' then 1 else ProfileId end in
(select case when #MediaType2 = '' then 1 else Splvalue end
from dbo.Split(case #MediaType2 when '0,' then '2,12,13' when '' then '1,' else #MediaType2 end,','))
and
case when #MediaType3 = '' then 1 else ProfileId end in
(select case when #MediaType3 = '' then 1 else Splvalue end
from dbo.Split(case #MediaType3 when '0,' then '1,14,15,16' when '' then '1,' else #MediaType3 end,','))
end
Basically, what I want to achieve is when '0' is passed in #MediaType1 variable, it should return all records which have category (1,2,3,4) else it should only that category which is passed (e.g. 3) else if its blank, it should show all records. Same way for #MediaType2 and #MediaType3 except that they should check for ProfileId. The condition is also that all three or two or one of the parameters could be blank, I need to handle those and show the filtered records.
My above query works only if one parameter is passed and rest all are blank. I also tried
where
(#MediaType1 <> '' and Category in (select Splvalue from dbo.Split(#MediaType1,',')))
or
(#MediaType2 <> '' and ProfileId in (select Splvalue from dbo.Split(#MediaType2 ,',')))
or
(#MediaType3 <> '' and ProfileId in (select Splvalue from dbo.Split(#MediaType3 ,',')))
but even this does not works. Any help would be appreciated
If I just rewrite what you said as conditions:
SELECT * FROM table
WHERE
(#MediaType1 = '' OR (#MediaType1 = 0 AND CategoryId IN (1,2,3,4))
OR #MediaType1 = CategoryId)
AND
(#MediaType2 = '' OR (#MediaType2 = 0 AND ProfileId IN (1,2,3,4))
OR #MediaType2 = ProfileId )
AND
(#MediaType3 = '' OR (#MediaType3 = 0 AND ProfileId IN (1,2,3,4))
OR #MediaType3 = ProfileId )
I just wrote the SP like this and it worked
Create proc Search
(
#MediaType1 varchar(1000),
#MediaType2 varchar(1000),
#MediaType3 varchar(1000)
)
as
begin
if (#MediaType1 = '' and #MediaType2 = '' and #MediaType3 = '')
begin
set #MediaType1 = '0,';
set #MediaType2 = '0,';
set #MediaType3 = '0,';
end
select * from table
where
((#MediaType1 = '0,' and CategoryId in (1,2,3,4)) or (CategoryId in (select Splvalue from dbo.Split(#MediaType1,','))))
or
((#MediaType2 = '0,' and ProfileId in (2,12,13)) or (ProfileId in (select Splvalue from dbo.Split(#MediaType2 ,','))))
or
((#MediaType3 = '0,' and ProfileId in (1,14,15,16)) or (ProfileId in (select Splvalue from dbo.Split(#MediaType3 ,','))))
end

SQL if else stored procedure

I'm writing a stored procedure and it's working for if but not for else. For if I'm getting the correct ID value but for else it's just giving me null.
SELECT #ID = ID FROM PRODUCTS WHERE SN = #SN
SELECT #Chip_ID = Chip_ID FROM PRODUCTS WHERE SN = #SN
SELECT #Power = Power From Module_Cycle WHERE ChipID = #Chip_ID
SELECT #Test_ID=Test_ID FROM TestEE_Mod WHERE ID=#ID AND #TypeID = TypeID
IF(#Test_ID IS NOT NULL)
BEGIN
IF(#TypeID = '3')
BEGIN
SELECT #Temp_TestID=TestID FROM TempCycle WHERE ChipID = #Chip_ID AND #Power = 'false'
BEGIN
UPDATE TestEE_Mod SET Temp_TestID = #Temp_TestID WHERE ID = #ID AND TypeID = #TypeID
END
END
ELSE
BEGIN
SELECT #Temp_TestID=TestID FROM TempCycle WHERE ChipID = #Chip_ID AND #Power = 'true'
BEGIN
UPDATE TestEE_Mod SET Temp_TestID = #Temp_TestID WHERE ID = #ID AND TypeID = #TypeID
END
END
END
Most likely the issue lies in the #Power variable. In your two SELECT statements, the only difference is that one includes #Power = 'false' in the WHERE clause, while the other includes #Power = 'true'.
Since #Power is a variable, not an actual column in your TempCycle table, I'm guessing you actually meant to filter by Power = #Power in both of them.

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^

SQL: If var = '' do nothing else add a condition to a WHERE clause

I would like to perform one part of a WHERE clause on the condition that a variable has a value. I have tried writing this in many different ways but always hit an error and was wondering if someone could help.
The code below is my current SQL statement that works but will return nothing if my #itemId is empty. I would only like to reduce the results if the #itemId as a value.
DECLARE #itemId nvarchar(max)
SET #itemId = 'someId'
SELECT
SalesOrdersItems.Id,
CASE
WHEN SalesOrderItems.ItemType = 'P' THEN Products.ProductId
WHEN SalesOrderItems.ItemType = 'S' THEN Sundries.SundryId
WHEN SalesOrderItems.ItemType = 'F' THEN FreightMethods.FreightMethodId
ELSE SalesOrderItems.FreeTextItem
END AS ItemId
FROM SalesOrderItems
LEFT OUTER JOIN Products ON SalesOrderItems.Product = Products.Product
LEFT OUTER JOIN Sundries ON SalesOrderItems.Sundry = Sundries.Sundry
LEFT OUTER JOIN FreightMethods ON SalesOrderItems.FreightMethod = FreightMethods.FreightMethod
WHERE
SalesOrdersItems.area LIKE 'SE%'
AND (Products.ProductId = #itemId OR Sundries.SundryId = #itemId OR FreightMethods.FreightMethodId = #itemId OR SalesOrderItems.FreeTextItem = #itemId)
I have tried writing the last line like this(see code below) but it doesn't work.
AND CASE
WHEN #itemId = '' THEN 1
ELSE (Products.ProductId = #itemId OR Sundries.SundryId = #itemId OR FreightMethods.FreightMethodId = #itemId OR SalesOrderItems.FreeTextItem = #itemId)
END
Does anyone have any ideas where I am going wrong?
If I'm misunderstanding please let me know, I'm assuming that if you have a blank #itemID you want all results, otherwise you'll limit the results.
WHERE SalesOrdersItems.area LIKE 'SE%'
AND ((#itemId != ''
AND (Products.ProductId = #itemId
OR Sundries.SundryId = #itemId
OR FreightMethods.FreightMethodId = #itemId
OR SalesOrderItems.FreeTextItem = #itemId))
OR #itemId = '')
I believe I have the parens correct, but they might be uneven. Hopefully it is it clear enough to understand my intent.
...
WHERE
1 = CASE WHEN ... THEN 1 ELSE 0 END
...
You could probably use NULLIF()
AND CASE
WHEN NULLIF(#itemId, '') IS NULL THEN 1
ELSE (Products.ProductId = #itemId OR Sundries.SundryId = #itemId OR FreightMethods.FreightMethodId = #itemId OR SalesOrderItems.FreeTextItem = #itemId)
END
As per my understanding, you should do something like below.
(Products.ProductId = #itemId OR ISNULL(#itemId, '') = '') OR
(Sundries.SundryId = #itemId OR ISNULL(#itemId, '') = '') OR
(FreightMethods.FreightMethodId = #itemId OR ISNULL(#itemId, '') = '') OR
(FreightMethods.FreeTextItem = #itemId OR ISNULL(#itemId, '') = '')
Hope this helps!!