How to pass in sql "like" condition from c# with single quotes - c#

I have string variable in c#
String Condition = " And LoginName like ''%"+txtLoginName.text+"%''";
I pass this condition variable to a stored procedure like this:
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "GetAllUserMasterBySearch";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#Condition ", Condition );
And my stored procedure is here:
create PROCEDURE [dbo].[GetAllUserMasterBySearch] (
#Condition nvarchar(max)
)
as
declare #Query nvarchar(max)
set #Query = 'SELECT
[UserMasterId], [LoginName], [UserName],
[UserType], [MobileNo], [Email],
[IsLogin], [IpAddress]
FROM
UserMaster
WHERE
IsActive = 1 ' + #Condition
print #query
EXEC sp_executesql #Query
How to pass "like" condition from C# ?

You can pass only variable and rewrite your SP as following
alter PROCEDURE [dbo].[GetAllUserMasterBySearch] (
#var nvarchar(max)
) as
declare #Query nvarchar(max)
set #Query = 'SELECT
[UserMasterId]
,[LoginName]
,[UserName]
,[UserType]
,[MobileNo]
,[Email]
,[IsLogin]
,[IpAddress]
FROM
UserMaster
WHERE
IsActive=1 AND LoginName LIKE %' + #var + '%';
print #query
EXEC sp_executesql #Query
Update: If you want to play with dynamic SQL then try ''' instead of ''. Honestly I haven't deal with dynamic SQL for a while since it it terrible and not secure approach (as it was already mentioned in comments)

Related

How to return filtered rows using SQL Cursors

I have been looking at examples of cursors in stored procedures and all of them seem to be either printing to the console or manipulating data in the main loop.
My situation is as follows:
Create a stored procedure that returns filtered rows from a single table.
Create a cursor for a simple SELECT statement without a WHERE clause.
Iterate through the fetch cycle.
Return only rows that meet certain criteria.
Pseudocode (C#, EntityFrameworkCore):
var name = "xyz";
var email = "";
var users = new List<User>();
foreach (var user in context.Users.AsQueryable())
{
var added = false;
if (!added)
{
if ((!string.IsNullOrWhitespace(name)) && (user.Name.Contains(name)))
{
users.Add(user);
}
}
if (!added)
{
if ((!string.IsNullOrWhitespace(email)) && (user.Name.Contains(email)))
{
users.Add(user);
}
}
}
These conditions can be complex enough to not be able to fit in a WHERE clause. Hence looking at cursors.
Just not sure how to think about this. A cursor is an iterator but how do you accumulate filtered rows to return?
Any advice would be appreciated.
Here is the stored procedure I would like to use cursors in:
CREATE OR ALTER PROCEDURE SpUserSearch
#Condition BIT = 0, -- AND=0, OR=1.
#Name NVARCHAR(100) = NULL,
#Email NVARCHAR(100) = NULL
AS
BEGIN
SET NOCOUNT ON;
DECLARE #UseName BIT
DECLARE #UseEmail BIT
IF ((#Name IS NULL) OR (LEN(#Name) = 0)) SET #UseName = 0 ELSE SET #UseName = 1
IF ((#Email IS NULL) OR (LEN(#Email) = 0)) SET #UseEmail = 0 ELSE SET #UseEmail = 1
IF (#Condition = 0)
SELECT [Id], [Name], [Email]
FROM [User]
WHERE
((#UseName = 1) OR ([Name] LIKE '%' + #Name + '%'))
AND
((#UseEmail = 1) OR ([Email] LIKE '%' + #Email + '%'))
ELSE
SELECT [Id], [Name], [Email]
FROM [User]
WHERE
((#UseName = 1) OR ([Name] LIKE '%' + #Name + '%'))
OR
((#UseEmail = 1) OR ([Email] LIKE '%' + #Email + '%'))
RETURN (##ROWCOUNT)
END
This type of query is called a Kitchen Sink query.
This can have issues due to parameter sniffing. So the best way to do this is not to use a cursor, but to dynamically build the conditions, and execute it using sp_executesql.
Note how the actual values are not concatenated in, but are also passed through as parameters to the dynamic side.
CREATE OR ALTER PROCEDURE SpUserSearch
#Condition BIT = 0, -- AND=0, OR=1.
#Name NVARCHAR(100) = NULL,
#Email NVARCHAR(100) = NULL
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sql nvarchar(max) = N'
SELECT [Id], [Name], [Email]
FROM [User]
WHERE 1=1 AND (
';
DECLARE #conditions nvarchar(max);
IF NULLIF(#Name, '') IS NOT NULL
SET #conditions = '([Name] LIKE ''%'' + #Name + ''%'')' + '
';
IF NULLIF(#Email, '') IS NOT NULL
SET #conditions = CONCAT(
#conditions + CASE WHEN #Condition = 0 THEN 'AND ' ELSE 'OR ' END + '
',
'([Email] LIKE ''%'' + #Email + ''%'')
');
SET #sql += #conditions + '
);
RETURN (##ROWCOUNT);
';
PRINT #sql; --for testing
DECLARE #rc int;
EXEC #rc = sp_executesql
#sql,
N'#Name NVARCHAR(100), #Email NVARCHAR(100)',
#Name = #Name,
#Email = #Email;
RETURN #rc;
END
I agree with the others that a cursor sounds like a really bad fit for your use case. But to answer your question, you would first create a temp table, then the cursor could insert any matching rows to the temp table as it looks through the data. At the end, select all rows from the temp table.

Conversion failed when converting the varchar value ' AND ID =' to data type int

I was looking how I can parameterize table names and so I found dynamic sql queries. I finally got the proc saved, but when I execute it errors out with "Conversion failed when converting the varchar value ' AND ID =' to data type int." I have no idea what is going wrong when I try to execute this stored proc. I feel like it must be a typo but I cannot tell. The stored pro.
EDITED to incorporate the suggestion below. Still no luck unless I am doing this wrong.
-- =======================================================
-- Create Stored Procedure Template for Azure SQL Database
-- =======================================================
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <Author, , Name>
-- Create Date: <Create Date, , >
-- Description: <Description, , >
-- =============================================
ALTER PROCEDURE [dbo].[sp_GetFormFieldCDC]
(
#formfieldId INT,
#C___operation INT,
#C___start_lsn binary(10),
#tablename NVarchar(255)
)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON
DECLARE #ActualTableName AS NVarchar(255)
SELECT #ActualTableName = QUOTENAME( TABLE_NAME )
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = #tablename
DECLARE #sql AS NVARCHAR(MAX)
SELECT #sql = 'SELECT * FROM ' + #ActualTableName + ' WHERE __$start_lsn =' + CONVERT(NVARCHAR(255),#C___start_lsn) + ' AND __$operation =' + #C___operation + ' AND ID =' + #formfieldId + ';'
-- Insert statements for procedure here
EXEC sp_executesql #SQL, N' #formfieldId INT,
#C___operation INT,
#C___start_lsn binary(10),
#tablename NVarchar(255)', #formfieldId ,
#C___operation,
#C___start_lsn,
#tablename
END
GO
You should pass the parameters all the way through to sp_executesql. Do not inject them, unless they are object names, in which case you need QUOTENAME.
You can also use OBJECT_ID to check for table existence, and throw an exception if there is no such object.
CREATE OR ALTER PROCEDURE [dbo].[GetFormFieldCDC]
(
#formfieldId INT,
#C___operation INT,
#C___start_lsn binary(10),
#schemaname sysname,
#tablename sysname
)
AS
SET NOCOUNT ON;
IF (OBJECT_ID(QUOTENAME(#schemaname) + '.' + QUOTENAME(#tablename)) IS NULL)
THROW 50000, 'Table not found', 0;
DECLARE #sql AS NVARCHAR(MAX) = '
SELECT *
FROM ' + QUOTENAME(#schemaname) + '.' + QUOTENAME(#tablename) + '
WHERE __$start_lsn = #C___start_lsn
AND __$operation = #C___operation
AND ID = #formfieldId;
';
EXEC sp_executesql #SQL,
N' #formfieldId INT,
#C___operation INT,
#C___start_lsn binary(10)',
#formfieldId = #formfieldId,
#C___operation = #C___operation,
#C___start_lsn = #C___start_lsn;
GO

How to get the Table result from the store procedure?

I have tried to write the store procedure with some condition check inside the Where syntax.
But it only shows the status of the query instead of result.
Could any body help to resolve this issue.
Please find the query
declare #query varchar(200)
declare #option varchar(10) = 'A'
set #query ='select * from TableName'+
(case when #query = ''
then
'where ColumnName = 1 '
end)
execute sp_sqlexec #query
Your query should be
declare #query varchar(200)
declare #option varchar(10) ='A'
declare #search as int=1
select #query ='select * from TableName '+
case when #option ='A'
then
' where ColumnName = '+ cast(#search as varchar(200))
else ''
end
execute sp_sqlexec #query
see demo
What i can see for sure is lack of space before where condition.
declare #query varchar(200)
declare #option varchar(10) = 'A'
set #query ='select * from TableName'+
(case when #query = ''
then
' where ColumnName = 1 '
end)
You can try like this :
declare #query varchar(200)
declare #option varchar(10) = 'A'
set #query ='select * from TableName '
if #option ='A'
set #query = #query + ' where ColumnName = 1 '
--print #query
execute sp_sqlexec #query
declare #query nvarchar(max)
, #option varchar(10) = 'A';
set #query = N'select * from TableName '
+ CASE WHEN #option IS NOT NULL
THEN N' where ColumnName = 1 ' ELSE N'' END
execute sp_executesql #query;
Avoid using sp_sqlexec it is very old and not supported anymore, use sp_executesql instead.

c# adding a variable in a SQL dynamic pivot string

I am trying to show the results of a dynamic pivot in a c# datagridview. So far I have got the following code but I am stumped as how to incorporate the #Date variable in the #query string. What am I missing here? The code works fine with hard coded dates and as it is returns Additional information: Incorrect syntax near '#Date'. Please help,
Thanks,
A
da2.SelectCommand = new SqlCommand(#"DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
SET #cols = STUFF((SELECT distinct ',' + QUOTENAME(currency)
FROM Alpha.dbo.Beta
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET #query = 'SELECT Customer, ' + #cols + ' FROM
(
SELECT
Customer, Amount, Currency
FROM Alpha.dbo.Beta
WHERE Date Between ''2010-01-01'' and '#Date' ----PROBLEM AREA----
) x
PIVOT
(
SUM(Amount)
for Currency in (' + #cols + ')
) AS pvt
ORDER BY Customer; '
execute(#query)", MyConnection);
da2.SelectCommand.Parameters.Add("Date", SqlDbType.DateTime).Value = dateTimePicker4.Text;
ds2.Clear();
da2.Fill(ds2);
Correct your code as:
da2.SelectCommand.Parameters.Add("#Date", SqlDbType.DateTime);
da2.SelectCommand.Parameters["#Date"].Value = dateTimePicker4.Text;
Also, use stored procedure instead the query.

Pass Column Name as parameter

I want to PassColumn name as a paremeter in My SP
And if my tat column exists in first table (Batch_Master), want to fatch value from that column,
And if that column exists in my second table (GTIN_Master), want to fetch value from tat table column,
Each table have columns like..
Batch_Master (Batch_M_id, GTIN(primary key),....etc
GTIN_Master (GTIN (foreign key),..etc)
I have Batch_M_id, and column name as a parameter..
Note: column Name having random datatype, some time int or some time datetime etc
I Try followin SP
CREATE PROCEDURE dbo.StoredProcedure2
#columnName varchar(50),
#batchmId int
AS
if exists(select * from sys.columns
where Name = N'columnName' and Object_ID = Object_ID(NBatch_Master'))
begin
select #columnName from Batch_Master
end
else
begin
select #columnName
from GTIN_Master inner join Batch_Master
on GTIN_Master.GTIN = Batch_Master.GTIN
where Batch_M_id =#batchmId
end
RETURN
What you need when you do not know exactly the query structure you are going to execute, then you have to create a dynamic query, which is actually a form of templating queries.
CREATE PROCEDURE dbo.StoredProcedure2
#columnName varchar(50),
#batchmId int
AS
DECLARE #SQL1 AS VARCHAR(MAX)
DECLARE #SQL2 AS VARCHAR(MAX)
SET #SQL1 = 'select ' + #columnName + ' from Batch_Master'
SET #SQL1 = 'select ' + #columnName + '
from GTIN_Master inner join Batch_Master
on GTIN_Master.GTIN = Batch_Master.GTIN
where Batch_M_id =' + CONVERT(VARCHAR,#batchmId)
IF EXISTS(SELECT * FROM sys.columns WHERE Name = #columnName and Object_ID = Object_ID(N'Batch_Master'))
BEGIN
EXEC (#SQL1)
END
ELSE
BEGIN
EXEC (#SQL2)
END
The above will do what you want but is prone to errors. For instance what if the column passed in the parameter does not exist in the tables used in the second query? You should probably need to check for existence in the second case too.
DECLARE #SQL VARCHAR(MAX)
SET #SQL = 'select ' + #columnName + ' from Batch_Master'
EXECUTE(#SQL)
This SQL:
set nocount on
go
create table One (id int, name varchar(25))
go
create table Two (id int, value varchar(25))
go
insert into One values (1, 'Table One')
insert into Two values (1, 'Table Two')
go
create procedure sp_test_colname
#colname sysname
as
declare #sql nvarchar(2048)
if exists (select 1 from sys.columns where name = #colname and object_id = object_id(N'One'))
set #sql = 'select [' + #colname + '] from [One]'
else
if exists (select 1 from sys.columns where name = #colname and object_id = object_id(N'Two'))
set #sql = 'select [' + #colname + '] from [Two]'
if #sql <> ''
exec sp_executesql #sql
go
exec sp_test_colname 'name'
exec sp_test_colname 'value'
exec sp_test_colname 'somethingelse'
go
drop procedure sp_test_colname
drop table One, Two
Returns the following:
name
-------------------------
Table One
value
-------------------------
Table Two

Categories