I'm trying to create a function that takes the parameters for the column, the table, the limit, and offset. Basically, I want to be able to get a specified number of rows data from a specified table from a specified column.
However, I'm unable to get the following code to work - I get several errors such as:
syntax error, unexpected SELECT, expecting ':' in: "create function get_banana(lim int, off int, tbl varchar(32), col varchar(32)) r"
syntax error, unexpected RETURN in: "return"
syntax error, unexpected END in: "end"
These errors seem kind of meaningless.
My code is as follows:
CREATE FUNCTION GET_BANANA(lim int, off int, tbl varchar(32), col varchar(32))
RETURNS TABLE (clm int)
BEGIN
PREPARE SELECT col FROM tbl LIMIT ? OFFSET ?;
RETURN EXEC (lim, off);
END;
I'd appreciate any help :) Thanks!
I see at least two issues
EXEC needs the identifier that is returned by PREPARE, e.g.:
sql>prepare select * from tables;
execute prepared statement using: EXEC 2(...)
sql>exec 2();
The function parameters tbl and col are string values. You cannot use them as table/column identifiers.
Having said that, I am not even sure if PREPARE can be used inside a function.
No, PREPARE is a top-level statement modifier.
Related
I keep getting the error : "Parameters were not supplied" for a very simple table-valued function. I cannot figure out what is the issue. I narrowed the function down to :
create FUNCTION udf_XX_OddFCST()
RETURNS #output TABLE (
articlecode nvarchar(50)
)
AS
BEGIN
insert into #output(articlecode) values ('abc');
RETURN
END
So I get the error when executing
select * from udf_XX_OddFCST
Any help would be greatly appreciated.
kind regards
you need to use parentheses in your function call :
SELECT * FROM udf_XX_OddFCST()
however as it has been mentioned in the comments, it would be more simpler and more efficient using iTVF:
CREATE FUNCTION udf_XX_OddFCST()
RETURNS TABLE
AS
RETURN (select 'abc' as articlecode)
SELECT * FROM udf_XX_OddFCST()
I have the following function which returns the following result set when this string is called.
SELECT item
FROM dbo.DelimitedSplit8K('985B773F-5E36-47D4-9E84-E0CE35B34337,32237666-86F3-41FD-BCDE-794571CDAEA2',',')
Result set:
item
------------------------------------
985B773F-5E36-47D4-9E84-E0CE35B34337
32237666-86F3-41FD-BCDE-794571CDAEA2
Now the purpose of this function is to get the two or more IDs cause I will be passing multiple IDs from my C# program to one variable in my stored procedure.
Problem
The problem seems to be simple enough but I am not sure as to why it's occurring.
CREATE PROC [dbo].[usp_printMulitTest]
#multiApplicationId_FK uniqueidentifier = '',
#pDelimiter CHAR(1) = NULL
AS
;WITH image_CTE(imgBinary, imgCode, appID) AS
(
SELECT
[image], imageCode_FK, app
FROM
[dbo].Images
WHERE
CAST('985B773F-5E36-47D4-9E84-E0CE35B34337,32237666-86F3-41FD-BCDE-794571CDAEA2' AS UNIQUEIDENTIFIER)
IN ((SELECT item
FROM dbo.DelimitedSplit8K(CAST('985B773F-5E36-47D4-9E84-E0CE35B34337,32237666-86F3-41FD-BCDE-794571CDAEA2' AS UNIQUEIDENTIFIER),',')))
)
SELECT *
FROM image_CTE
This stored procedure works fine when I hard code the variables.
However, when I convert it to this
WHERE CAST(app AS UNIQUEIDENTIFIER)
IN((SELECT item FROM dbo.DelimitedSplit8K(CAST(#multiApplicationId_FK AS UNIQUEIDENTIFIER),',' )))
to get the results for the app IDs that I pass in, I get an error
Conversion failed when converting from a character string to uniqueidentifier
While looking for solutions two that were pointed out is the incorrect formation of the unique identifier and not using cast, however I checked the numbers and used a cast/convert and there has been no change.
Grateful for assistance in this.
In a SQL Server database, one can use table variables like this:
declare #table as table (a int)
In an Azure Data Warehouse, that throws an error.
Parse error at line: 1, column: 19: Incorrect syntax near 'table'
In an Azure Data Warehouse, you can use temporary tables:
create table #table (a int)
but not inside functions.
Msg 2772, Level 16, State 1, Line 6 Cannot access temporary tables
from within a function.
This document from Microsoft says,
◦Must be declared in two steps (rather than inline): ◾CREATE TYPE
my_type AS TABLE ...; , then ◾DECLARE #mytablevariable my_type;.
But when I try this:
create type t as table (a int);
drop type t;
I get this :
Msg 103010, Level 16, State 1, Line 1 Parse error at line: 1, column:
8: Incorrect syntax near 'type'.
My objective is to have a function in an Azure Data Warehouse which uses a temporary table. Is it achievable?
Edit Start Here
Note that I am not looking for other ways to create one specific function. I have actually done that and moved on. I'm a veteran programmer but an Azure Data Warehouse rookie. I want to know if it's possible to incorporate some concept of temporary tables in an Azure Data Warehouse function.
Ok, I believe this is what you are after.
Firstly, this uses a Table Value Function, which are significantly faster than Scalar or Multi-statement Table value Functions.
Secondly, there was no use for a Table Variable, or Temporary Table, just some good odd string manipulation, a bit of maths, and a CTE. Definitely no expensive WHILE loop.
I've tested this against the examples in the link, and they all return the expected values.
USE Sandbox;
GO
CREATE FUNCTION ValidateHealthNumber (#HealthNumber varchar(10))
RETURNS TABLE
AS
RETURN
WITH Doubles AS(
SELECT CONVERT(tinyint,SUBSTRING(V.HN,O.P,1)) AS HNDigit,
CONVERT(tinyint,SUBSTRING(V.HN,O.P,1)) * CASE WHEN O.P % 2 = 0 THEN 1 ELSE 2 END ToAdd
FROM (VALUES(#HealthNumber)) V(HN)
CROSS APPLY (VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9)) O(P)),
Parts AS (
SELECT CONVERT(tinyint,SUBSTRING(CONVERT(varchar(2),ToAdd),1,1)) AS FirstDigit, --We know that the highest value can be 18 (2*9)
CONVERT(tinyint,SUBSTRING(CONVERT(varchar(2),ToAdd),2,1)) AS SecondDigit --so no need for more than 2 digits.
FROM Doubles)
SELECT CASE RIGHT(#HealthNumber, 1) WHEN 10 - RIGHT(SUM(FirstDigit + SecondDigit),1) THEN 1 ELSE 0 END AS IsValid
FROM Parts;
GO
CREATE TABLE #Sample(HealthNumber varchar(10));
INSERT INTO #Sample
VALUES ('9876543217'), --Sample
('5322369835'), --Valid
('7089771195'), --Valid
('8108876957'), --Valid
('4395667779'), --Valid
('6983806917'), --Valid
('2790412845'), --not Valid
('5762696912'); --not Valid
SELECT *
FROM #Sample S
CROSS APPLY ValidateHealthNumber(HealthNumber) VHN;
GO
DROP TABLE #Sample
DROP FUNCTION ValidateHealthNumber;
If you don't understand any of this, please do ask.
No you can't. Object can't be created inside User Defined Functions (UDF). Use table variables instead.
If you want yo use user defined type, first create it outside the UDF and use it as a variable type within the UDF.
-- Create the data type
CREATE TYPE TestType AS TABLE
(
Id INT NOT NULL,
Col1 VARCHAR(20) NOT NULL)
GO
-- Create the tabled valued function
CREATE FUNCTION TestFunction
()
RETURNS
#Results TABLE
(Result1 INT, Result2 INT)
AS
BEGIN
-- Fill the table variable with the rows for your result set
DECLARE #Var1 TestType;
RETURN
END
GO
I have migrated a database from oracle, and now have a few Scalar-valued Functions.
However, when I call them, I get an error saying:
Cannot find either column "dbo" or the user-defined function or aggregate "dbo.chk_mgr", or the name is ambiguous.
I'm calling it like this:
SELECT dbo.chk_mgr('asdf')
What am I doing wrong?
Are you sure it's not a Table-Valued Function?
The reason I ask:
CREATE FUNCTION dbo.chk_mgr(#mgr VARCHAR(50))
RETURNS #mgr_table TABLE (mgr_name VARCHAR(50))
AS
BEGIN
INSERT #mgr_table (mgr_name) VALUES ('pointy haired boss')
RETURN
END
GO
SELECT dbo.chk_mgr('asdf')
GO
Result:
Msg 4121, Level 16, State 1, Line 1
Cannot find either column "dbo" or the user-defined function
or aggregate "dbo.chk_mgr", or the name is ambiguous.
However...
SELECT * FROM dbo.chk_mgr('asdf')
mgr_name
------------------
pointy haired boss
Can do the following
PRINT dbo.[FunctionName] ( [Parameter/Argument] )
E.g.:
PRINT dbo.StringSplit('77,54')
That syntax works fine for me:
CREATE FUNCTION dbo.test_func
(#in varchar(20))
RETURNS INT
AS
BEGIN
RETURN 1
END
GO
SELECT dbo.test_func('blah')
Are you sure that the function exists as a function and under the dbo schema?
You are using an inline table value function. Therefore you must use Select * From function.
If you want to use select function() you must use a scalar function.
https://msdn.microsoft.com/fr-fr/library/ms186755%28v=sql.120%29.aspx
Make sure you have the correct database selected. You may have the master database selected if you are trying to run it in a new query window.
I have the following MySQL routine:
DELIMITER $$
CREATE DEFINER=`root`#`%` PROCEDURE `getGroupOrders`(grp INT,
ord CHAR(20),
srt CHAR(4),
page INT,
count INT)
BEGIN
SELECT *
FROM `dbre`.`order_info`
WHERE username IN (SELECT `dbre`.`users`.`username`
FROM `dbre`.`users`
WHERE `dbre`.`users`.`id_group` = grp)
ORDER BY ord srt LIMIT page,count;
END
As you can see, I want to pass the ordering column and sorting as a parameters, however I get a syntax error is there a way to do this or do I have to make similar routines for each type of ordering?
I don't think this is possible in the way you try it.
You cannot use a variable to define the ORDER BY column an direction.
The only workaround I can think of is to create a prepared statement from a dynamically created string (where you can use the variables to specify the order by details) and then execute that prepared statement.
Here is an example of such a dynamic statement:
http://forums.mysql.com/read.php?98,393613,393642#msg-393642