SQL scalar valued function throwing "Invalid Object Name" error - sql-server

My SQL scalar valued function is defined in the following code:
CREATE FUNCTION CtrAmount ( #Ctr_Id int )
RETURNS MONEY
AS
BEGIN
DECLARE #CtrPrice MONEY
SELECT #CtrPrice = SUM(amount)
FROM Contracts
WHERE contract_id = #Ctr_Id
RETURN(#CtrPrice)
END
GO
SELECT * FROM CtrAmount(345)
GO
But when it comes to the SELECT line, I am getting this error:
Msg 208, Level 16, State 3, Line 14
Invalid object name 'CtrAmount'.

Int(10) - unknown type
CREATE FUNCTION dbo.CtrAmount
(
#Ctr_Id INT
)
RETURNS MONEY
AS
BEGIN
RETURN (
SELECT SUM(amount)
FROM dbo.Contracts
WHERE contract_id = #Ctr_Id
)
END
GO
SELECT dbo.CtrAmount(345)
GO

Related

Snowflake case statement to return multiple columns value in procedure

Below is the snowflake procedure in am trying to run.
CREATE OR REPLACE PROCEDURE test()
RETURNS VARCHAR(16777216)
LANGUAGE SQL
AS
$$
DECLARE
V_LAT varchar;
V_LNG varchar;
BEGIN
INSERT INTO test.crs_compact.case_test
(
c_address,
c_comment
)
SELECT
(CASE WHEN c_nationkey = 0 then (:V_LAT=a.c_address, :V_LNG=c_comment)
END)
from "SNOWFLAKE_SAMPLE_DATA"."TPCH_SF1"."CUSTOMER" as a;
return 'Data Loaded Successfully';
END;
$$
while calling the procedure getting below error.
Uncaught exception of type 'STATEMENT_ERROR' on line 11 at position 1 : SQL compilation error: error line 7 at position 3 Invalid argument types for function 'IFF': (BOOLEAN, ROW(BOOLEAN, BOOLEAN), NULL)
(a.c_address, c_comment) or (:V_LAT=a.c_address, :V_LNG=c_comment) is a ROW
you cannot put a ROW inside a CASE (which is also an IFF)..
Where you have typed looks like you are trying to do this:
SELECT
a.c_address, c_comment
from "SNOWFLAKE_SAMPLE_DATA"."TPCH_SF1"."CUSTOMER" as a
WHERE c_nationkey = 0;
Or more to the point:
INSERT INTO test.crs_compact.case_test
(
c_address,
c_comment
)
SELECT
a.c_address, c_comment
from "SNOWFLAKE_SAMPLE_DATA"."TPCH_SF1"."CUSTOMER" as a
WHERE c_nationkey = 0;
Now if you want those null values instead of skipping them:
INSERT INTO test.crs_compact.case_test
(
c_address,
c_comment
)
SELECT
iff(c_nationkey = 0, a.c_address, NULL)
,iff(c_nationkey = 0, c_comment, NULL)
from "SNOWFLAKE_SAMPLE_DATA"."TPCH_SF1"."CUSTOMER" as a;

Invalid STRING_SPLIT args in SQL Server

I am trying to parse a cell that is data type nvarchar(max) like it is csv in SQL Server 2017. I was hoping to use the STRING_SPLIT return a row of data for each value in the array-like string. However, when I run the following code I get an error.
select this_column
into #t
from that_table
where coordinate_x = 1
and coordinate_y = 7
select * from STRING_SPLIT(#t.this_column, ',')
Msg 4104, Level 16, State 1, Line 16
The multi-part identifier "#t.this_column" could not be bound
Msg 8116, Level 16, State 1, Line 16
Argument data type void type is invalid for argument 1 of string_split function
How can I parse this data?
You can't pass a table to a inline table function, you need to include it in your FROM:
SELECT {YourColumns}
FROM #t T
CROSS APPLY STRING_SPLIT(T.this_column, ',') SS;
You'll want to use a cross apply with your temp table
Here's a working example so you can see how that works:
DECLARE #TestData TABLE
(
[TestData] NVARCHAR(MAX)
);
INSERT INTO #TestData (
[TestData]
)
VALUES ( N'1,2,3,4,5,6,7,8,9');
SELECT [b].[value] FROM #TestData [a]
CROSS APPLY[STRING_SPLIT([a].[TestData], ',') [b];
So for your situation, just a small tweak to what you already have, something like:
SELECT [b].[value] FROM #t a
CROSS APPLY STRING_SPLIT(a.this_column,',') b

How to convert string array to int array in T-Sql

I got a sql function that returns a string array,..., now I want to convert it into an int array,
Msg 245, Level 16, State 1, Line 14 Conversion failed when converting
the varchar value ',' to data type int.
My code :
DECLARE #ListZoneId as varchar(200);
SET #ListZoneId = [dbo].[CMS_fGetListOfZoneIdByParentZoneId](1)
//sql function return string array : '1,22,30,14'
declare #tempTb table
(
TempId int
)
while charindex(',',#ListZoneId) > 0
begin
insert into #tempTb select substring(#ListZoneId,1,1)
SET #ListZoneId = substring(#ListZoneId,3,len(#ListZoneId))
end
SELECT COUNT(*) from Shop as s inner join ShopInZone as z on s.Id=z.ShopId inner join Zone as zo on zo.Id = z.ZoneId
where z.ZoneId IN ( select * from #tempTb)

Issue creating function with a "with"

I am trying to create this function(variable names changed so allow naming mistakes as when tested original without function works fine),
CREATE FUNCTION [dbo].[GetQuality](#FruitID VARCHAR(200))
RETURNS varchar(200)
AS
BEGIN
DECLARE #Result varchar(200)
SET #Result = (
WITH
latest AS
(
SELECT * FROM (SELECT TOP 1 * FROM Fruits_Crate WHERE FruitID like #FruitID ORDER BY ExpiryDate DESC) a
),
result AS
(
SELECT
latest.ExpiryDate as LatestExpiryDate, latest.Size as LatestSize, latest.Weight as LatestWeight,
previous.ExpiryDate as PreviousExpiryDate, previous.Size as PreviousSize, previous.Weight as PreviousWeight,
CASE SIGN((latest.Weight * latest.Size) - (previous.Weight * previous.Size))
WHEN 1 THEN 'Increased'
WHEN 0 THEN 'Static'
WHEN -1 THEN 'Decreased'
ELSE 'No Previous Data'
END AS Movement
FROM (SELECT TOP 1 * FROM (SELECT TOP 2 * FROM Fruits_Crate WHERE FruitID like #FruitID ORDER BY ExpiryDate DESC) x ORDER BY ExpiryDate) previous
FULL OUTER JOIN latest ON previous.FruitID = latest.FruitID
)
SELECT result.Movement AS FruitMovement from result;
)
RETURN #Result
END
Error
Msg 156, Level 15, State 1, Procedure GetQuality, Line 10
Incorrect syntax near the keyword 'WITH'.
Msg 319, Level 15, State 1, Procedure GetQuality, Line 10
Incorrect syntax near the keyword 'with'. If this statement is a common table expression, an xmlnamespaces clause or a change tracking context clause, the previous statement must be terminated with a semicolon.
Msg 102, Level 15, State 1, Procedure GetQuality, Line 14
Incorrect syntax near ','. Msg 102, Level 15, State 1, Procedure GetQuality, Line 31 Incorrect syntax near ')'.
I think you can move the assignment down, and put a semi colon before the with, and all should be good.
CREATE FUNCTION [dbo].[GetQuality](#FruitID VARCHAR(200))
RETURNS varchar(200)
AS
BEGIN
DECLARE #Result varchar(200);
WITH
latest AS
(
SELECT * FROM (SELECT TOP 1 * FROM Fruits_Crate WHERE FruitID like #FruitID ORDER BY ExpiryDate DESC) a
),
result AS
(
SELECT
latest.ExpiryDate as LatestExpiryDate, latest.Size as LatestSize, latest.Weight as LatestWeight,
previous.ExpiryDate as PreviousExpiryDate, previous.Size as PreviousSize, previous.Weight as PreviousWeight,
CASE SIGN((latest.Weight * latest.Size) - (previous.Weight * previous.Size))
WHEN 1 THEN 'Increased'
WHEN 0 THEN 'Static'
WHEN -1 THEN 'Decreased'
ELSE 'No Previous Data'
END AS Movement
FROM (SELECT TOP 1 * FROM (SELECT TOP 2 * FROM Fruits_Crate WHERE FruitID like #FruitID ORDER BY ExpiryDate DESC) x ORDER BY ExpiryDate) previous
FULL OUTER JOIN latest ON previous.FruitID = latest.FruitID
)
SELECT #RESULT = result.Movement AS FruitMovement from result;
RETURN #Result
END

SQL server can not accept median function

I wrote this Median function but it is executing with errors.. Can someone guide me what's wrong in the code?
BEGIN
CREATE TABLE #ITEMORDERDETAILS
(
ITEM CHAR(15),
QTYSHP DECIMAL(21, 6),
RQDATE DATETIME
)
DECLARE #Median FLOAT
DECLARE #ITEM CHAR(15)
DECLARE #ORDERCNT INT
SET #ITEM=#ITEMN
INSERT #ITEMORDERDETAILS
SELECT ITEM,
QTYSHP,
RQDATE
FROM tbl123456
WHERE PRICE != '0'
AND SALESMN != 'WB'
AND RQDATE > ( getdate () - 180 )
AND ITEM = #ITEM
UNION
SELECT ITEM,
QTYSHP,
RQDATE
FROM tbl123
WHERE PRICE != '0'
AND SALESMN != 'WB'
AND RQDATE > ( getdate () - 180 )
AND ITEM = #ITEM
SELECT #ORDERCNT = count (1)
FROM #ITEMORDERDETAILS
--SELECT #ORDERCNT
SELECT #Median = ( sum(QTYSHP) / #ORDERCNT )
FROM #ITEMORDERDETAILS
SELECT #Median AS 'Median'
--SELECT * from #ITEMORDERDETAILS
DROP TABLE #ITEMORDERDETAILS
RETURN #Median
END
ERRORS
Msg 2772, Level 16, State 1, Procedure
f_Get_Average_Order_Size_Median, Line 34 Cannot access temporary
tables from within a function.
Msg 2772, Level 16, State 1, Procedure
f_Get_Average_Order_Size_Median, Line 35 Cannot access temporary
tables from within a function.
Msg 2772, Level 16, State 1, Procedure
f_Get_Average_Order_Size_Median, Line 42 Cannot access temporary
tables from within a function.
Msg 156, Level 15, State 1, Procedure
f_Get_Average_Order_Size_Median, Line 46 Incorrect syntax near the
keyword 'SELECT'.
The reason is in your error message:
Line 34 Cannot access temporary tables from within a function
If you make a function, there are limits to what you can access.
However, if you use SQL Server 2012, you do not need to write your own median function but you can use PERCENTILE_DISC
PERCENTILE_DISC (0.5) WITHIN GROUP (ORDER BY XXXX)
OVER (PARTITION BY YYYY) AS Median

Resources