I am doing searching with 4 parameters with no mandatory fields
The Parameters are
City
Marital Status
Gender
Groups
As per the selection I am getting SQL queries like this
select * from UserTable
where Gender='Male' AND City='' AND MaritalStatus='Single' AND Groups =''
It returns 0 rows as the parameters City='' AND Groups ='' is not matching the criteria.
Is there any way to achieve this without going to check for null in multiple combinations.I am using MSSQL2012 as my database and Asp.Net C#.
My method is as follows
private void GetSearchResults(string city, string MaritalStatus, string Gender, string Groups)
{
var qry="select * from UserTable
where Gender='"+Gender+"' AND City='"+city+"' AND MaritalStatus='"+MaritalStatus+"' AND Groups ='"+Groups+"'";
}
What about my selection group='' Means I don't want any filtration on Group
select * from UserTable where Gender='Male' AND City IS NULL AND MaritalStatus='Single' AND Groups IS NULL
suppose you have below parameters
#Gender = 'Male',
#City = '',
#MaritalStatus = 'Married'
#Groups = ''
and your sql looks like.
select * from UserTable
where
(Gender = #Gender OR ISNULL (#Gender, '') = '')
AND (City = #City OR ISNULL (#City, '') = '')
AND (MaritalStatus = #MaritalStatus OR ISNULL (#MaritalStatus, '') = '')
AND (Groups = #Groups OR ISNULL (#Groups, '') = '')
Related
I am trying to access the values retrieved values from a stored procedure. I think it retrieves the values but it is showing null.
I'm coding using C#.
My code:
var result = cont1.somemethod("101");
var values = result .GetResult<sampleclass>().ToList<sampleclass>();// showing the retrieved 3 resultset values as null
My method:
[Function(Name = "sample_sp")]
[ResultType(typeof(sampleclass))]
public IMultipleResults somemethod([Parameter(DbType = "VarChar(100)")] string Id)
{
IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())),Id);
return ((IMultipleResults)(result.ReturnValue));
}
My procedure:
DECLARE #temp1 TABLE (Details nvarchar(max));
SELECT ColumnName, value
INTO #temp1
FROM
(SELECT
CAST(id AS NVARCHAR(MAX)) [ID],
CAST(firstname AS NVARCHAR(MAX)) [First Name],
CAST(lastname AS NVARCHAR(MAX)) [Last Name],
FROM
table1
WHERE
id = '101') d
UNPIVOT
(Value FOR
ColumnName IN ([ID], [First Name], [Last Name])
) unpiv;
SELECT Details[Member Details] FROM #temp1
Results from stored procedure call:
Member Details
---------------
ID : 101
First Name : aaa
Last Name : bbb
And my CS[sampleclass] file,
private string _details;
[Column(Storage = "_details", DbType = "nvarchar(max)")]
public string details
{
get { return this._details; }
set {
if ((this._details != value))
{
this._details = value;
}
}
}
which part of the code is wrong?
Can anyone help me with the correct way?
DECLARE #temp1 TABLE (Details nvarchar(max));
select ColumnName,value into #temp1
#temp1 is a table VARIABLE.
#temp1 is a temporary table.
These are two separate variables, you should use one or the other, not both.
Now i got the Result by
changing the Temporary table name.
Replace 'select Details[Member Details] from #temp1' to 'select * from #temp1'
May any one tells whats the difference between these two queries
select Details[Member Details] from #temp1 // shows null in c# code
and
select * from #temp1 // shows values
I'm passing a string variable to an IN Clause in sql (Stored Procedure). When declaring and setting the variable in sql I get back all the data that is required. But when setting the variable from c# I'm only receiving data based on the first status within that paramater.
I've got a function to split the statuses in the paramater list to retrieve the records:
ALTER FUNCTION [dbo].[fnSplit](
#sInputList VARCHAR(8000)
, #sDelimiter VARCHAR(10) = ';'
) RETURNS #List TABLE (item VARCHAR(8000))
BEGIN
DECLARE #sItem VARCHAR(8000)
WHILE CHARINDEX(#sDelimiter,#sInputList,0) <> 0
BEGIN
SELECT
#sItem=RTRIM(LTRIM(SUBSTRING(#sInputList,1,CHARINDEX(#sDelimiter,#sInputList,0)-1))),
#sInputList=RTRIM(LTRIM(SUBSTRING(#sInputList,CHARINDEX(#sDelimiter,#sInputList,0)+LEN(#sDelimiter),LEN(#sInputList))))
IF LEN(#sItem) > 0
INSERT INTO #List SELECT #sItem
END
IF LEN(#sInputList) > 0
INSERT INTO #List SELECT #sInputList
RETURN
END
My stored procedure is built like this:
ALTER procedure [dbo].[Get_RequestsAtEachStage]
(#managerRef int,
#status varchar(20))
as
BEGIN
WITH MaxStatusDate
as
(
select rs.requestID,rs.status from (
SELECT requestID,MAX([DateCreated]) AS MaxDate
FROM [LoanRequest].[dbo].[requestStatus]
GROUP BY RequestID) maxg
inner join [LoanRequest].[dbo].[requestStatus] rs on maxg.requestid = rs.requestid and maxg.MaxDate = rs.DateCreated
)
SELECT lr.ID, lr.serialNo, lr.model, lr.clientName, lr.address, lr.telephone, lr.contactName,
lr.swop, lr.substitueOfGoods, lr.printFunction, lr.copyFunction, lr.scanFunction,
lr.faxFunction, lr.controller, lr.controllerEmailAddress,
ml.Name, wl.Location, rt.requestType AS RequestTypeName, rs.status
FROM [dbo].[loanRequest] lr
INNER JOIN [dbo].[managersList] ml ON lr.managerRef = ml.ID
INNER JOIN [dbo].[warehouseList] wl ON lr.warehouseID = wl.ID
INNER JOIN [dbo].[requestType] rt ON lr.requestType = rt.ID
INNER JOIN MaxStatusDate rs ON lr.ID = rs.requestID
WHERE (#managerRef is null or lr.managerRef = #managerRef) AND rs.status IN (SELECT item FROM [dbo].[fnSplit](#status, ';'))
END
Based on the page the user access it will send through the appropriate statusses and retrieve the necessary records.
Setting the paramaters in sql as follows works perfect, I retrieve all the records:
DECLARE #managerRef INT
DECLARE #status NVARCHAR(100)
SET #managerRef = NULL
SET #status = 'Allocated;Readings Updated'
But, when I send it through c# within a string, it only retrieves records with the status of Allocated.:
string status = "Allocated;Readings Updated";
DataTable dtDevices = d.PopulateDevicesApproval(managerRef, status);
My method to retrieve the data from sql:
string filterstring = "";
filterstring = "Get_RequestsAtEachStage ";
cn = new SqlConnection(GetConnectionString());
SqlCommand myCmd = new SqlCommand(filterstring, cn);
myCmd.CommandType = CommandType.StoredProcedure;
cn.Open();
myCmd.Parameters.AddWithValue("#managerRef", managerRef);
myCmd.Parameters.AddWithValue("#status", status);
DataTable dt = new DataTable();
dt.Load(myCmd.ExecuteReader());
return dt;
Is there anything I am doing wrong?
--------- EDIT -----------
Running SELECT item FROM [dbo].fnSplit results from both c# and sql
Returning results from c#:
And returning results from sql:
So I have a drop down list(ASP.NET) with some values retrieved from sqldatasource. And I added a item name 'ALL' with a value -1 to retrieve all the values in that field(the field is varchar). But it do-sent work. Please help how can i get all the values instead of a specific one.
the 'All' Value is -1 witch is passed to the parameter #NAME but it do-sent work
Query:
SELECT USERINFO.USERID, USERINFO.NAME, USERINFO.TITLE,
CHECKINOUT.CHECKTIME, CHECKINOUT.CHECKTYPE FROM USERINFO INNER JOIN
CHECKINOUT ON USERINFO.USERID = CHECKINOUT.USERID WHERE NAME = #NAME
AND CHECKTIME BETWEEN #startDate AND #endDate + ' 23:59:00.000'
SELECT USERINFO.USERID, USERINFO.NAME, USERINFO.TITLE,
CHECKINOUT.CHECKTIME, CHECKINOUT.CHECKTYPE FROM USERINFO INNER JOIN
CHECKINOUT ON USERINFO.USERID = CHECKINOUT.USERID
WHERE ( NAME = #NAME and #NAME<> -1 ) OR (#NAME = -1 and 1=1)
AND CHECKTIME BETWEEN #startDate AND #endDate + ' 23:59:00.000'
Basically , the condition 1=1 is used to ignore condition in where clause for particular value passed to variable , in this case #NAME
I have such tables in my database like Customer, Member, Instructor, Employee etc. Each of these users has his email adrress. I need to check if there is already a user with given email. I was thinking about:
Check each table, something like this:
public bool IsEmailAddressExists(string email)
{
if (!Context.Customers.Any(c => string.Equals(c.Email, email, StringComparison.InvariantCultureIgnoreCase)))
if (!Context.Members.Any(m => string.Equals(m.Email, email, StringComparison.InvariantCultureIgnoreCase)))
...
}
Select all emails and check:
public bool IsEmailAddressExists(string email)
{
var emails = Context.Customers.Select(c => c.Email).Union(Context.Members.Select(m => m.Email))...; //other unions
return emails.Any(e => string.Equals(e, email, StringComparison.InvariantCultureIgnoreCase));
}
There are more tables and many users, so I would like to know what would be the most efficient way to implement such kind of checking.
Thank you.
It sounds like you have a couple of options.
Create a view. You could create a view in the database that shows, say, email addresses only. Assuming you're using MSSQL Server, something like:
CREATE VIEW EmailView AS
SELECT Email from Customers
UNION ALL
SELECT Email from Instructors
....
... then using an entity bound to that view so you can check the list of emails to see if that email exists already. Check out the documentation for more information.
Normalize your database. Do each of these tables share common information beyond email, say, first name and/or last name? It might be worth your time to reorganize your data model to put that information in a "Persons" table, then foreign key your other tables to it. (This will also help if your users are two different things, say, a customer and an instructor.)
In pure SQL this would be your most efficient because it stops searching as soon as it hits a match:
... As a stored procedure:
CREATE PROCEDURE EmailExists
#email varchar(254) = NULL
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE #emailExists bit
SET #emailExists = 0
SELECT #emailExists = 1 WHERE EXISTS(SELECT 1 FROM Customer WHERE email = #email)
IF #emailExists = 0
BEGIN
SELECT #emailExists = 1 WHERE EXISTS(SELECT 1 FROM Member WHERE email = #email)
IF #emailExists = 0
BEGIN
SELECT #emailExists = 1 WHERE EXISTS(SELECT 1 FROM Instructor WHERE email = #email)
IF #emailExists = 0
BEGIN
SELECT #emailExists = 1 WHERE EXISTS(SELECT 1 FROM Employee WHERE email = #email)
END
END
END
SELECT #emailExists
END
... As a scalar-valued function:
CREATE FUNCTION EmailExists
(
#email varchar(254)
)
RETURNS bit
AS
BEGIN
DECLARE #emailExists bit
SET #emailExists = 0
SELECT #emailExists = 1 WHERE EXISTS(SELECT 1 FROM Customer WHERE email = #email)
IF #emailExists = 0
BEGIN
SELECT #emailExists = 1 WHERE EXISTS(SELECT 1 FROM Member WHERE email = #email)
IF #emailExists = 0
BEGIN
SELECT #emailExists = 1 WHERE EXISTS(SELECT 1 FROM Instructor WHERE email = #email)
IF #emailExists = 0
BEGIN
SELECT #emailExists = 1 WHERE EXISTS(SELECT 1 FROM Employee WHERE email = #email)
END
END
END
-- Return the result of the function
RETURN #emailExists
END
In C# with Linq, you can use the Any extension and the || operator. Since Any usually gets translated to EXISTS in SQL and evalutation of the || operator in C# is lazy, evaluation will stop as soon as the first ocurrence of an email is reached.
bool emailExists = customerEmails.Any(e => string.Equals(e, email, StringComparison.InvariantCultureIgnoreCase))
|| memberEmails.Any(e => string.Equals(e, email, StringComparison.InvariantCultureIgnoreCase))
|| instructorEmails.Any(e => string.Equals(e, email, StringComparison.InvariantCultureIgnoreCase))
|| employeeEmails.Any(e => string.Equals(e, email, StringComparison.InvariantCultureIgnoreCase));
i have the this MYSQL SP that does SUm against different tables but i wanted the SP to return all the results in one table one row i tried using + to combine results from the selects but it gets error
DROP PROCEDURE IF EXISTS x.GetFinanceContent;
delimiter //
CREATE PROCEDURE x.GetFinanceContent
(
IN userId INT
)
BEGIN
(SELECT SUM(AMOUNT) AS creditTotal
FROM x.Card1
WHERE user_Id = userId and card_type=1)
+
(SELECT SUM(AMOUNT) AS debitTotal
FROM x.Card2
WHERE user_Id = userId and card_type=2)
END;//
Error Code: 1064 You have an error in
your SQL syntax; check the manual that
corresponds to your MySQL server
version for the right syntax to use
near '+ (SELECT SUM(AMOUNT) AS
debitTotal
FROM x.Card
WHERE user_Id ' at line 10 0.000 sec
SELECT
( SELECT SUM(AMOUNT) AS creditTotal
FROM x.Card1
WHERE user_Id = userId AND card_type=1
)
, ( SELECT SUM(AMOUNT) AS debitTotal
FROM x.Card2
WHERE user_Id = userId AND card_type=2
)
If you want to SUM those sums you can make query like this:
SELECT ((SELECT SUM(AMOUNT) AS creditTotal
FROM x.Card1
WHERE user_Id = userId and card_type=1) +
(SELECT SUM(AMOUNT) AS debitTotal
FROM x.Card2
WHERE user_Id = userId and card_type=2)) as total
Use union http://dev.mysql.com/doc/refman/5.0/en/union.html If you want to get one result set....
DROP PROCEDURE IF EXISTS x.GetFinanceContent;
delimiter //
CREATE PROCEDURE x.GetFinanceContent
(
IN userId INT
)
BEGIN
(SELECT SUM(AMOUNT) AS creditTotal
FROM x.Card1
WHERE user_Id = userId and card_type=1)
UNION
(SELECT SUM(AMOUNT) AS debitTotal
FROM x.Card2
WHERE user_Id = userId and card_type=2)
END;//
Although I am rusty now with SQL and too lazy to check if syntax is correct, I think it should work.