What this dynamic query missing and doesn't return a result? - asp.net

I have following scalar function but the problem is that it doesn't return actual result but returns a query.
Could somebody guide me on it what I am missing here or making wrong?
I have formed the following function
ALTER function test(#QueId int, #Answer varchar(250)) RETURNS VARCHAR(500) AS
BEGIN
DECLARE #STR varchar(4000)
DECLARE #QRY AS VARCHAR(1000)
SELECT #QRY=
'SELECT #str = COALESCE(#str + '';'','''') + AnswerText '+
'FROM SurveyQuestionAnswerTypes WHERE AnswerType=(Select AnswerType From SurveyQuestions Where QuestionID=' +
CAST(#QueId AS VARCHAR(4)) + ')AND AnswerValue in (' + replace(#Answer,'^',',') +')'
--EXEC sp_executesql #QRY, '#STR VARCHAR(4000)', #STR
RETURN #QRY
END
Instead of returning a result it returns
SELECT #str = COALESCE(#str + ';','') + AnswerText
FROM SurveyQuestionAnswerTypes
WHERE AnswerType = (Select AnswerType
From SurveyQuestions
Where QuestionID=25)AND AnswerValue in (3,4,5,6)

Well - it returns the query because you told it to do so!
Look at your code: you have commented out the line that would actually execute the dynamic SQL (EXEC sp_executsql .....), and instead you're returning the query (#QRY) as a string:
--EXEC sp_executesql #QRY, '#STR VARCHAR(4000)', #STR
RETURN #QRY
Just change that to execute the query instead of returning its string representation....

Try this syntax, this might work for you:
Exec (#QRY)

You cannot execute "exec" or "sp_executesql" nor can execute a stored procedure in a function.
you can refer this
blog
OR this SO question

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.

Sybase IQ, return the result of a query string in a variable inside a function with "execute"?

Hi can you help me please?, That way I can return the result of a query string in a variable inside a function with "execute"?.
for example
create function my _funcion(in # num_celular char (20), in # str_comando char (120))
returns char (120)
- on exception resume
as
begin
set # exec_qry = Select 1 from dummy
execute (# exec_qry)
return (# the return value of the query "execute")
end
go
thanks
Try this way:
create function my_funcion(#num_celular char (20), #str_comando char (120))
returns char(120)
as
begin
DECLARE #Result char(120)
execute('select #Result = ''Aaa'' ' )
RETURN #Result
end
go
Result of below query
select my_funcion('AA','BB')
is
Aaa
Ok, thanks for answering my question, but look at the issue is much more complex because we are running a Dynamic Sql, formed in while loop to the query is then stored in one string variables and running it, the problem are the function promptly made ​​as follows and is attached below.
create function ms_trafico.fn_mov_cambia_tag( in #num_celular char(20), in #str_comando char(120) )
returns char(120)
--on exception resume
as
begin
set nocount on
set temporary option string_rtruncation='OFF'
--aplican para isql
--set option isql_print_result_set=ALL
--set option isql_show_multiple_result_sets=On
declare #comando varchar(100)
declare #exec_qry varchar(500)
declare #cadena varchar(60)
declare #tag char(15)
declare #columna char(20)
declare #pos int
declare #strCadFinal char(150)
declare #strFono char(20)
set #comando = trim(#str_comando)
set #strFono = trim(#num_celular)
set #exec_qry='select XXX '
set #pos = 1
print "comando " + #comando
while(#pos <= locate(#comando,'<',-1))
begin
set #tag = substr(#comando,locate(#comando,'<',#pos),CHARINDEX('>', SUBSTR(#comando,locate(#comando,'<',#pos),length(#comando))))
set #pos = locate(#comando,'<',#pos) + 1
select atributo_campo into #columna from TB_MOV_MAPEO_COMANDOS where parametro = #tag
set #cadena="replace(XXX,'"||trim(#tag)||"',"||trim(#columna)||")"
set #exec_qry=replace(#exec_qry,'XXX',#cadena)
end
set #comando="'"||trim(#comando)||"'"
set #exec_qry=replace(#exec_qry,'XXX',#comando)
set #exec_qry=#exec_qry||' as comando INTO #strCadFinal FROM VM_ALL_SERVICES_MOVIL where num_celular=#strFono'
execute (#exec_qry)
return (#strCadFinal) "The result of my query with execute method"!!!!!!!!!!
end
go
Thanks for you attention.

SQL stored procedure sent data for "IN" condition

I have a stored procedure and it has where condition using 'IN' key word. So I want to send more than one value to stored procedure .
This is my stored procedure:
ALTER PROCEDURE [dbo].[xxx]
#COM_KEY varchar(max) = NULL
AS
BEGIN
SELECT
UserName, UserId
FROM
company
WHERE
(COM_KEY IN (#COM_KEY))
END
So I pass the value in here
string companyID = "";
for (int i = 0; i < lbCompanies.Items.Count; i++)
{
if (i == 0)
{
companyID += Convert.ToInt32(lbCompanies.Items[i].Value);
}
else
{
companyID += "," + Convert.ToInt32(lbCompanies.Items[i].Value);
}
}
DataSet ApproveList = DataRepository.TUsersProvider.xxx(companyID);
but there is an error
Conversion failed when converting the varchar value '3087,4058' to data type int
How can I solve it?
You cannot pass a comma-delimited string into #COM_KEY. You should pass an array.
One way to accomplish this task would be using Table-Valued Parameters.
Have a look at this article, under Solution #3: TSQL: Passing array/list/set to stored procedure (MS SQL Server).
In essence, you treat your series of ints as a table you apply JOIN upon, and not query it via WHERE ... IN () phrase.
You can create a UserDefinedFunction which parses the string and puts each integer extracted into a table to solve this issue
CREATE Function fnSplitter (#IDs Varchar(100) )
Returns #Tbl_IDs Table (ID Int) As
Begin
-- Append comma
Set #IDs = #IDs + ','
-- Indexes to keep the position of searching
Declare #Pos1 Int
Declare #pos2 Int
-- Start from first character
Set #Pos1=1
Set #Pos2=1
While #Pos1<Len(#IDs)
Begin
Set #Pos1 = CharIndex(',',#IDs,#Pos1)
Insert #Tbl_IDs Select Cast(Substring(#IDs,#Pos2,#Pos1-#Pos2) As Int)
-- Go to next non comma character
Set #Pos2=#Pos1+1
-- Search from the next charcater
Set #Pos1 = #Pos1+1
End
Return
End
Now alter your stored procedure like this
ALTER PROCEDURE [dbo].[xxx]
#COM_KEY varchar(max) = NULL
AS
BEGIN
SELECT UserName, UserId
From company
WHERE COM_KEY IN (Select ID From dbo.fnSplitter(#COM_KEY))
END
Check this link for detailed Implemetation
The most trivial solution to your problem is to vale SQL string(for dynamic Query) and then execute the statement
ALTER PROCEDURE [dbo].[xxx]
#COM_KEY varchar(max) = NULL
AS
BEGIN
DECLARE #SQL nvarchar(MAX)
SET #SQL=N' SELECT
UserName, UserId
FROM
company
WHERE
(COM_KEY IN ('+#COM_KEY+'))'
EXCE #SQL
END
Solution mentioned by #ssilas777 is the sophisticated version for the same.
Also note that using IN is not always advisable. I have run into
query time out errors
when IN has lot of IDs
Change your code from:
if (i == 0)
{
companyID += Convert.ToInt32(lbCompanies.Items[i].Value);
}
else
{
companyID += "," + Convert.ToInt32(lbCompanies.Items[i].Value);
}
to:
if (i == 0)
{
companyID +="'" + Convert.ToInt32(lbCompanies.Items[i].Value) + "'";
}
else
{
companyID += ",'" + Convert.ToInt32(lbCompanies.Items[i].Value) + "'";
}

How to have a MySQL procedure return a boolean?

I want to create a procedure that takes in a string, searches the table and the specified column for that string, and returns a 1 if it finds it and a zero if it does not. I am relatively new to SQL and do not know the syntax or commands very well. I want something like this:
CREATE PROCEDURE dbo.GetUsername
(
#Username NCHAR(10)
)
AS
#boolVariable
SELECT #Username FROM Accounts
RETURN #boolVariable
You don't return a value, but instead supply that in a result set.
CREATE PROCEDURE GetUsername
(
#Username NCHAR(10)
)
AS
SELECT Username FROM Accounts WHERE Username = #UserName;
In your calling code, simply check for the existence of a row in the result set.
I'm not sure if you're looking for mysql or mssql solution.
delimiter //
drop procedure if exists search_string //
create procedure search_string (in str varchar(100))
begin
declare b,r bool;
select count(*) into r from your_table where your_field = str;
if r > 0 then
set b = 1;
else
set b = 0;
end if;
select b;
end; //
delimiter //
call search_string('searched_string');

SQL use comma-separated values with IN clause

I am developing an ASP.NET application and passing a string value like "1,2,3,4" into a procedure to select those values which are IN (1,2,3,4) but its saying "Conversion failed when converting the varchar value '1,2,3,4' to data type int."
Here is the aspx code:
private void fillRoles()
{
/*Read in User Profile Data from database */
Database db = DatabaseFactory.CreateDatabase();
DbCommand cmd = db.GetStoredProcCommand("sp_getUserRoles");
db.AddInParameter(cmd, "#pGroupIDs", System.Data.DbType.String);
db.SetParameterValue(cmd, "#pGroupIDs", "1,2,3,4");
IDataReader reader = db.ExecuteReader(cmd);
DropDownListRole.DataTextField = "Group";
DropDownListRole.DataValueField = "ID";
while (reader.Read())
{
DropDownListRole.Items.Add((new ListItem(reader[1].ToString(), reader[0].ToString())));
}
reader.Close();
}
Here is my procedure:
CREATE Procedure [dbo].[sp_getUserRoles](#pGroupIDs varchar(50))
AS BEGIN
SELECT * FROM CheckList_Groups Where id in (#pGroupIDs)
END
Here is a workaround I found to do what you are trying to achieve
CREATE Procedure [dbo].[sp_getUserRoles](
#pGroupIDs varchar(50)
)
As
BEGIN
SELECT * FROM CheckList_Groups Where (',' + #pGroupIDs +',' LIKE '%,' + CONVERT(VARCHAR, id) + ',%')
End
This gets your comma delimited list and compares it to the id's(which are represented like so ',1,', ',2,' etc) in the table using LIKE
If you dont want to use dynamic sql, the best way ive found is to create a function which turns a delimited string into a table, something like this works for an Integer list:
CREATE FUNCTION [dbo].[StringToIntList]
(#str VARCHAR (MAX), #delimeter CHAR (1))
RETURNS
#result TABLE (
[ID] INT NULL)
AS
BEGIN
DECLARE #x XML
SET #x = '<t>' + REPLACE(#str, #delimeter, '</t><t>') + '</t>'
INSERT INTO #result
SELECT DISTINCT x.i.value('.', 'int') AS token
FROM #x.nodes('//t') x(i)
ORDER BY 1
RETURN
END
Then use that in your sp:
CREATE Procedure [dbo].[sp_getUserRoles](
#pGroupIDs varchar(50)
)
As
BEGIN
SELECT * FROM CheckList_Groups Where id in (
SELECT ID FROM dbo.StringToIntList(#pGroupIds,',')
)
End
Sure it can't do that,
The generated query would be sth like this
SELECT * FROM CheckList_Groups Where id in ('1,2,3,4')
and sure it can't be executed.
you can build the query in your stored procedure then execute it with exec
'SELECT * FROM CheckList_Groups Where id in (' + #pGroupIDs + ')'
or
SELECT * FROM CheckList_Groups Where charindex(','+id+',' , #pGroupIDs)>0
but you first must add the ',' to start and end of your parameter in your c# code
It is not possible to put those values (the comma separated string) in a parameter-value.
What you'll have to do, is to create the SQL Statement in your stored procedure dynamically, by string concatenation. You'll have to execute it with the sp_executesql stored procedure then.
CREATE PROCEDURE [dbo].[getUserRoles]( #groupIds NVARCHAR(50) )
AS BEGIN
DECLARE #statement NVARCHAR(255)
SELECT #statement = N'SELECT * FROM CheckList_Groups Where id in ( ' + #pGroupIDs + N')'
execute sp_executesql #statement
END
Also, not that I named the SP getUserRoles instead of sp_getUserRoles.
The reason is very simple: when you execute a stored procedure whose name starts with sp_, then SQL Server will first query the master database to find that stored procedure, which causes a performance hit offcourse.
The way you are trying to do this is slightly wrong. You will need to use EXECUTE in order to achieve this.
CREATE PROCEDURE [dbo].[sp_getUserRoles](#pGroupIDs nvarchar(50))
As
BEGIN
EXECUTE (N'SELECT * FROM CheckList_Groups Where id in (' + #pGroupIDs + ')';
END
DECLARE #TagId NVARCHAR(100) = '43,81'
SELECT * FROM TABLE WHERE TagId IN (SELECT TRIM(VALUE) FROM STRING_SPLIT( #TagId , ',' ) )
USE STRING_SPLIT FUNCTION FOR THIS
You need to use SP_executesql to achieve this functionllity
CREATE Procedure [dbo].[sp_getUserRoles](
#pGroupIDs varchar(50)
)
As
BEGIN
EXECUTE sp_executesql
N'SELECT * FROM CheckList_Groups Where id in (#pGroupIDs)',
N'#level varchar(50)',
#level = #pGroupIDs;
End
The IN clause can't take a bound parameter like that. What it's being given when the query is actually created is SELECT * FROM CheckList_Groups Where id in ('1,2,3,4'). Essentially the IN clause is being passed a single string.
First create function -
Just run this code
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[CSVToTable] (#InStr VARCHAR(MAX))
RETURNS #TempTab TABLE
(id int not null)
AS
BEGIN
;-- Ensure input ends with comma
SET #InStr = REPLACE(#InStr + ',', ',,', ',')
DECLARE #SP INT
DECLARE #VALUE VARCHAR(1000)
WHILE PATINDEX('%,%', #INSTR ) <> 0
BEGIN
SELECT #SP = PATINDEX('%,%',#INSTR)
SELECT #VALUE = LEFT(#INSTR , #SP - 1)
SELECT #INSTR = STUFF(#INSTR, 1, #SP, '')
INSERT INTO #TempTab(id) VALUES (#VALUE)
END
RETURN
END
GO
Then -
Use function in bracket with select statment -
DECLARE #LIST VARCHAR(200)
SET #LIST = '1,3'
SELECT Id, Descr FROM CSVDemo WHERE Id IN (SELECT * FROM dbo.CSVToTable(#LIST))

Resources