Invalid Object Name Error in Function in SQL - asp.net

I have following function defined
alter FUNCTION [dbo].[GetXMLValues](#business_id int, #id varchar(30))
RETURNS varchar(30)
AS
BEGIN
declare #xmlValue varchar(30)
set #xmlValue = (SELECT top 1000 T.Content.value('(/XmlDataPairDocument/dataitem[#id=sql:variable("#id")]/#value)[1]', 'VARCHAR(100)')
FROM tblApplications T where t.business_id =#business_id)
return #xmlValue
END
WHen i hit F5 command Executes Successfully/...
but when i try to execute it using following query :
select * from [GetXMLValues](1,'sadfj')
it shows an error saying : Invalid object name 'GetXMLValues'.
what is the reason ? and what is error??

This is a Scalar function, not a Table-Valued function.
select dbo.[GetXMLValues](1,'sadfj')
should work.
You can't treat this like a table, i.e. select * ..., you need to just select the result directly as above.
See Types of Functions for more details.

As mentioned by t-clausen.dk and Ian Preston, it's because you have a Scalar function and not a table valued function.
I just wanted to extend on t-clausen.dk's post which switches your function to a multi-statement table valued function. I would take this a step further and actually use an inline table valued function:
ALTER FUNCTION [dbo].[GetXMLValues](#business_id int, #id varchar(30))
RETURNS TABLE
AS
RETURN (
SELECT top 1000 T.Content.value('(/XmlDataPairDocument/dataitem[#id=sql:variable("#id")]/#value)[1]', 'VARCHAR(100)')
FROM tblApplications T where t.business_id =#business_id
)
Which you then use in the same way:
select xmlValue from dbo.[GetXMLValues](1,'sadfj')
Check out:
Query performance and multi-statement table valued functions

your function is not returning a table, it is returning a varchar(30). The correct syntax to use your function would be:
select [dbo].[GetXMLValues](1,'sadfj')
Try function this instead:
ALTER FUNCTION [dbo].[GetXMLValues](#business_id int, #id varchar(30))
RETURNS #t table (xmlValue varchar(30))
AS
BEGIN
insert #t (xmlValue)
SELECT top 1000 T.Content.value('(/XmlDataPairDocument/dataitem[#id=sql:variable("#id")]/#value)[1]', 'VARCHAR(100)')
FROM tblApplications T where t.business_id =#business_id
return
end
Then you can call your function this way:
select xmlValue from dbo.[GetXMLValues](1,'sadfj')

Or if you do want a table function, try changing your function to be something like this - then you can use select * from...
ALTER FUNCTION [dbo].[GetXMLValues](#business_id int, #id varchar(30))
RETURNS
#outputTbl_xmlValue table
(
xmlValue varchar(30)
)
AS
BEGIN
INSERT #outputTbl_xmlValue SELECT top 1000 T.Content.value('(/XmlDataPairDocument/dataitem[#id=sql:variable("#id")]/#value)[1]', 'VARCHAR(100)')
FROM tblApplications T where t.business_id =#business_id)
return
END
GO

ALTER FUNCTION Isnulldate(#maxdate1 DATETIME,
#maxdate2 DATETIME,
#maxdate3 DATETIME)
returns DATETIME
AS
BEGIN
DECLARE #date DATETIME
IF #maxdate3 IS NOT NULL
BEGIN
SET #date=#maxdate3
RETURN #date
END
IF #maxdate2 IS NOT NULL
BEGIN
SET #date=#maxdate2
RETURN #date
END
IF #maxdate1 IS NOT NULL
BEGIN
SET #date=#maxdate1
RETURN #date
END
RETURN #date
END
## Execution ##
DECLARE #dateim DATETIME=Getdate()
SELECT dbo.Isnulldate(NULL, NULL, #dateim)

Related

how can i call stored procedure from the function in mariadb?

i want to get count of no.of rows present in table which i pass at runtime to a function.
i have created a procedure and function to execute dynamic queries. function will not allow dynamic query because i am calling procedure from function.
that procedure having dynamic query.
///////procedure///////
CREATE PROCEDURE bizopsgolddev.`test1`(tbnm varchar(100))
begin
declare sql_text varchar(200);
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
SELECT CONCAT(sql_text, ' is not valid');
END;
set sql_text=concat('select count(*) from ',tbnm);
SET #SQL := sql_text;
PREPARE stmt FROM #SQL;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
end;
//////function//////
DROP FUNCTION IF EXISTS xyz;
CREATE FUNCTION `xyz`(tname varchar(100)) RETURNS int(11)
begin
declare val int;
call test1(tname);
return 1;
end;
if i execute this //select xyz('axpdc')// it should return rows count
can any one tell me how can i get count by passing table name to function(in mariadb only)
As I understand the question, the solution would be a function that returns the row count of a table with it's name passed to the function as a parameter.
I think this could be done by querying the information_schema database in MariaDB. A function could look like this:
CREATE DEFINER = 'yourUsername'#'192.168.%'
FUNCTION testDataBase.fn_GetRowCount(tableName VARCHAR(128))
RETURNS int(11)
BEGIN
-- This could be a parameter if need it to be.
DECLARE databaseName varchar(40) DEFAULT 'testDataBase';
DECLARE result int DEFAULT -1;
SELECT t.TABLE_ROWS INTO result
FROM information_schema.TABLES t
WHERE t.TABLE_NAME = tableName
AND t.TABLE_SCHEMA = databaseName;
RETURN result;
END
In order for this to work the user mentioned as the definer must have read privilege to the TABLES table in the information_schema database, otherwise you might get an error (tbh, I don't know if this is necessary).
There is a lot of useful information to be grabbed from the information_schema database.

mariadb user defined aggregate function

I am using mariadb 10.3.9, and have created a user defined aggregate function (UDAF) and placed in a common_schema. This schema contains my utility functions to be used by other schema/databases on the same server.
The issue is that when calling the UDAF while using any other schema, it always return NULL!
The following is to demonstrate the issue:
CREATE SCHEMA IF NOT EXISTS common_schema;
DELIMITER $$
DROP FUNCTION IF EXISTS common_schema.add_ints $$
CREATE FUNCTION common_schema.add_ints(int_1 INT, int_2 INT) RETURNS INT NO SQL
BEGIN
RETURN int_1 + int_2;
END $$
DROP FUNCTION IF EXISTS common_schema.sum_ints $$
CREATE AGGREGATE FUNCTION common_schema.sum_ints(int_val INT) RETURNS INT
BEGIN
DECLARE result INT DEFAULT 0;
DECLARE CONTINUE HANDLER FOR NOT FOUND RETURN result;
LOOP FETCH GROUP NEXT ROW;
SET result = common_schema.add_ints(result, int_val);
END LOOP;
END $$
DELIMITER ;
Now, calling it this way, returns the result as expected:
USE common_schema;
SELECT common_schema.sum_ints(seq)
FROM (SELECT 1 seq UNION ALL SELECT 2) t;
-- result: 3
Calling it using any other schema, it returns NULL:
USE other_schema;
SELECT common_schema.sum_ints(seq)
FROM (SELECT 1 seq UNION ALL SELECT 2) t;
-- result: null
Am I missing something here? Is there any configuration that is missing?
Appreciate your help.
Reported as a Bug https://jira.mariadb.org/browse/MDEV-18100.
As a workaround, create the UDAF in every schema.

Convert stored proc to table to be able to use in select statement

I have to use existing stored procedure which returns REF CURSOR. I need to insert that resultset into a temporary table.
Spec of procedure is:
TYPE cur IS REF CURSOR;
PROCEDURE get(p_one NUMBER ,p_two OUT cur);
How can I insert the resultset of this procedure into a table.
I just re-read the title of your question. Do you actually need to be able to select from a procedure?
If so, this can be achieved by using pipelined functions.
The process for this is:
Create an object type to represent the record-type you require.
Create a nested table type of the object.
Create a pipelined function which returns the nest table.
You can then select from this function.
This example should get you on your way:
create or replace type to_test as object (
val1 varchar2(32),
val2 varchar2(32)
);
create or replace type tt_test as table of to_test;
create or replace function demo_pipe return tt_test pipelined
is
v_test to_test;
begin
for rec in (select * from user_tables) loop
v_test := to_test(rec.table_name, rec.tablespace_name);
pipe row (v_test);
end loop;
end;
/
select * from table(demo_pipe);

oracle pl sql function having errors

I want to create a function that returns the number of rows in a table called Rating with a where clause.Where am i going wrong before the declare statement and the end statement?
create or replace
FUNCTION get_movies(user IN NUMBER) RETURN NUMBER
IS
DECLARE cnt NUMBER;
BEGIN
SELECT count(*)
INTO cnt
FROM rating
where userid= user;
RETURN cnt;
END;
I will appreciate help.Thanks.
You should not have the DECLARE keyword. You only need that for an anonymous block (or a sub-block).
create or replace
FUNCTION get_movies(p_userid IN NUMBER) RETURN NUMBER
IS
cnt NUMBER;
BEGIN
...
user is a reserved word so I'd suggest not using that as your parameter name. In the where clause I'm not sure if it will use your parameter value, or the name of the user executing the function; which would error as that string value couldn't be implicitly converted to a number.

How to use Split function in stored procedure?

I am selecting the values like below:
select browser, firstname, lastname from details
Here the browser value will be like this:
33243#Firefox#dsfsd
34234#google#dfsd
And separately I have used split function for single value as below:
select * from dbo.split('33243#Firefox#dsfsd','#')
Result is:
items
===========
33243
firefox
dsfsd
So I have used split function like below
select split(browser, '#'), firstname, lastname from details
but its not working...
What I need is
33243#Firefox#dsfsd
instead of displaying the value like this into the grid,
have to display only Firefox into the grid.
Since you know you want the second element each time, you could write a function like this:
CREATE FUNCTION [dbo].[fn_SplitElement]
(
#inputString nvarchar(2000), --The input string
#elem int, --The 1-based element index to return,
#delimiter nvarchar(1) --The delimiter char
)
RETURNS nvarchar(2000)
AS
BEGIN
-- Declare the return variable here
DECLARE #result nvarchar(2000)
-- Add the T-SQL statements to compute the return value here
SELECT #result = value
FROM
(
SELECT *,ROW_NUMBER() OVER(ORDER By Position) as rownum FROM dbo.split(#inputString,#delimiter)
) as t
WHERE rownum=#elem
-- Return the result of the function
RETURN #result
END
GO
Then you can call:
select [dbo].[fn_SplitElement](browser,2,'#') as 'BrowserName', firstname, lastname from details
You do not state which version of SQL Server you are using or which split function. However, most split functions return a table rather than rows so you'll need to use a JOIN to join the two tables (the first is the split, the second is the rest of the fields).
For more information in SQL split functions, see Erland Sommarskog's page at http://www.sommarskog.se/arrays-in-sql.html .
You can Create a Split function and that will be use when you want.
CREATE FUNCTION [dbo].[Split]
(
#List nvarchar(max),
#SplitOn nvarchar(1)
)
RETURNS #RtnValue table (
Id int identity(1,1),
Value nvarchar(max)
)
AS
BEGIN
While (Charindex(#SplitOn,#List)>0)
Begin
Insert Into #RtnValue (value)
Select
Value = ltrim(rtrim(Substring(#List,1,Charindex(#SplitOn,#List)-1)))
Set #List = Substring(#List,Charindex(#SplitOn,#List)+len(#SplitOn),len(#List))
End
Insert Into #RtnValue (Value)
Select Value = ltrim(rtrim(#List))
Return
END
after that you can call the function in your query as below.
SELECT * FROM anotherTable WHERE user_id IN(dbo.split(#user_list,','))
I Have used below query instead of using split function.. its working perfectly..
select
SUBSTRING(SUBSTRING(browser, CHARINDEX ('#', browser)+1,LEN(browser)-charindex('#', browser)),
0,
CHARINDEX('#',SUBSTRING(browser, CHARINDEX ('#', browser)+1,LEN(browser)-CHARINDEX('#', browser)))),
firstname, lastname from details

Resources