我有一个表单,用户可以指定各种参数来挖掘一些数据(状态,日期等).
我可以生成一个查询:
SELECT * FROM table WHERE:
status_id = 3
date = <some date>
other_parameter = <value>
Run Code Online (Sandbox Code Playgroud)
每个WHERE都是可选的(我可以选择所有行status = 3,或所有行date = 10/10/1980,或所有行status = 3 AND date = 10/10/1980等).
给定大量参数,都是可选的,构成动态存储过程的最佳方法是什么?
我正在研究各种数据库,例如:MySQL,Oracle和SQLServer.
我正在使用SQL Server 2008 Express,并且我有一个SELECT基于参数从表中执行的存储过程.我有nvarchar参数和int参数.
这是我的问题,我的where子句看起来像这样:
WHERE [companies_SimpleList].[Description] Like @What
AND companies_SimpleList.Keywords Like @Keywords
AND companies_SimpleList.FullAdress Like @Where
AND companies_SimpleList.ActivityId = @ActivityId
AND companies_SimpleList.DepartementId = @DepartementId
AND companies_SimpleList.CityId = @CityId
Run Code Online (Sandbox Code Playgroud)
此参数是由我的ASP.NET MVC 3应用程序的用户设置的过滤器值,并且int参数不能设置,所以其价值将是0.这是我的问题,存储过程将搜索谁拥有的项目0为CityId为例如,为此,它返回错误的结果.因此,如果int参数的值大于0,那么能够拥有动态where子句会很好.
提前致谢
如何以编程方式将搜索条件添加到SQL存储过程?在我的应用程序(C#)中我正在使用存储过程(SQL Server 2008R2)
ALTER PROCEDURE [dbo].[PROC001]
@userID varchar(20),
@password varchar(20)
AS
SELECT * FROM tUsers WHERE RTRIM(Name) = @userID AND RTRIM(Password) = @password
Run Code Online (Sandbox Code Playgroud)
我希望通过更多条件扩展此查询,现在我不知道有多少条件将使用此查询,因为程序执行... 2,3,6或20.我想以编程方式添加这些条件,如:
SELECT * FROM tUsers WHERE RTRIM(Name) = @userID AND RTRIM(Password) = @password
AND Field2 = '1' AND Field3 = '0' OR Field4 <> '8' AND Field5 < '100' ....
Run Code Online (Sandbox Code Playgroud)
是否可以动态地向存储过程发送条件?
我必须在sql 2008中编写一个搜索查询,它可以使用多个可选
参数.
Date From: ...
Date To: ...
UserType: ...
Customer: ...
User: ...
A user can select any of the above search parameters.
I am planning to use either the separate select statements for different cases, or
to use coalesce etc.
Please suggest what would be best possible way out.
Run Code Online (Sandbox Code Playgroud)
谢谢,
select当datetime参数(@StartDate&@EndDate)在此存储过程中是可选的时,如何在SQL Server中编写此查询?
CREATE PROCEDURE [dbo].[prSearchEmployees]
(
@Id INT = NULL
,@FullName VARCHAR(20) = NULL
,@Age INT = NULL
,@StartDate = NULL
,@EndDate = NULL
)
AS
BEGIN
SELECT *
FROM Employee
WHERE Id = ISNULL(@Id, Id)
AND FullName LIKE ISNULL(@FullName + '%', FullName)
AND Age = ISNULL(@Age, Age)
END
Run Code Online (Sandbox Code Playgroud) 我想知道是否有任何明智的方法来重写以下查询,以便优化器使用列上的索引?
Create Procedure select_Proc1
@Key1 int=0,
@Key2 int=0
As
BEGIN
Select key3
From Or_Table
Where (@key1 =0 OR Key1 =@Key1) AND
(@key2 =0 OR Key2 =@Key2)
END
GO
Run Code Online (Sandbox Code Playgroud)
即使WHERE子句中的列被索引覆盖,SQL Server也无法使用这些索引.这提出了一个问题,即是否有任何东西"阻止"索引的使用.这个问题的答案是肯定的 - 罪魁祸首是参数和"或"条件.索引不包含这些参数,这意味着SQL Server无法使用任何索引来评估"@ key1 = 0"(同样适用于@ key2 = 0的条件).实际上,这意味着SQL Server无法使用索引来评估子句"@ key1 = 0 OR Key1 = @ key1"(因为"OR"子句是两个条件所涵盖的行的并集).同样的原则也适用于其他条款(re.key2).这导致SQL Server得出结论,没有索引可用于提取行,使SQL Server能够利用下一个最佳方法 - 聚簇索引扫描
如您所见,如果WHERE子句中的谓词为"OR",则SQL优化器将不使用列上的索引.针对此问题的一种解决方案是使用IF子句为所有可能的参数组合分隔查询.
请阅读这篇简短的文章,以便更好地了解问题:http://www.sql-server-performance.com/articles/per/optimize_or_clause_p1.aspx
现在我的问题是,如果可能的组合只有三到四个,我们该怎么办?为每个组合编写单独的查询似乎不是一个合理的解决方案.这个问题还有其他解决方法吗?
这可能很明显,但我很困惑.
我有一个带有where子句的SQL查询(其中包含参数列表).如果所有这些参数都为null,我需要SQL忽略where子句并检索所有记录.在SQL中这很容易吗?我知道一种方法是,如果参数为null,只需使用代码删除where子句.
我正在尝试创建一个具有可选参数的存储过程.我按照这里列出的说明操作.我也引用了这个问题.但是我一直收到以下错误:
将数据类型varchar转换为int时出错.
当我执行它时,它工作
EXEC sp_get_user {id#}
Run Code Online (Sandbox Code Playgroud)
要么
EXEC sp_get_user NULL, {username}
Run Code Online (Sandbox Code Playgroud)
但失败了
EXEC sp_get_user {username}
Run Code Online (Sandbox Code Playgroud)
存储过程
@id int = NULL,
@username nvarchar(50) = NULL
SELECT
username = COALESCE(a.Username, b.Username),
password = COALESCE(a.Password, b.Password),
signup_date = COALESCE(a.SignedUpOn, b.Signup_Date)
FROM table1 a
FULL OUTER JOIN table 2 b
ON a.ID = b.ID
WHERE ((a.ID = @id OR @id IS NULL)
AND (a.Username = @username OR @username IS NULL)
OR (b.ID = @id OR @id IS NULL)
AND (b.Username …Run Code Online (Sandbox Code Playgroud) 考虑以下具有2个可选变量的函数
public List<T> SelectSqlItems<T>(
string settingsgroup = null,
int? state = null)
{
SqlCommand selectCommand = null;
if (settingsgroup == null)
{
selectCommand = new SqlCommand(
"select * from ApplicationSettings ", con);
}
else
{
selectCommand = new SqlCommand(
string.Format(
"select * from ApplicationSettings where settingsgroup='{0}' ",
settingsgroup),
con);
}
if (state != null)
{
selectCommand.CommandText +=
!selectCommand
.CommandText
.ToLower()
.Contains("where")
? string.Format("where state={0}", state)
: string.Format("and state={0}", state);
}
//etc..
}
Run Code Online (Sandbox Code Playgroud)
我有4种可能性:
settingsgroup==null && state==null
settingsgroup==null && state!=null
settingsgroup!=null …Run Code Online (Sandbox Code Playgroud) 我想根据提供的值自动附加where子句
让我们考虑一个包含select查询的存储过程
CREATE PROCEDURE [dbo].[example]
@From DATETIME,
@T0 DATETIME
AS
BEGIN TRY
SELECT *
FROM footable
WHERE Fromdate = @From AND Todate = @TO
END TRY
Run Code Online (Sandbox Code Playgroud)
如果@From的值为null,那么where子句必须是
SELECT *
FROM footable
WHERE Todate = @TO
Run Code Online (Sandbox Code Playgroud)
有没有办法实现这个?
非常感谢你的回答.但无论哪种,因为这并没有解决我的问题@From,并@To都是可选的.按照这种方法,我的代码会喜欢
SELECT *
FROM footable
WHERE (Fromdate = @From OR @From IS NULL)
AND (Todate = @TO OR @To IS NULL)
Run Code Online (Sandbox Code Playgroud)
执行此操作会导致整个表格.
我有许多连接的表,并且最大行数约为 400 万条记录。我们正在存储过程中搜索此表,并且有一个默认值为 NULL 的可选参数,下面是我们正在运行的编辑示例,连接中涉及更多表,但只有 1 个字段具有 WHERE 子句;
DECLARE @OwnerId VARCHAR (50)=NULL
SET @OwnerId = 'A123456'
SELECT DISTINCT
t1.Id,
t2.OwnerId,
FROM
table1 t1
INNER JOIN [table2] t2 m ON t1.Id = t2.id
WHERE
t2.OwnerId = @OwnerId
Run Code Online (Sandbox Code Playgroud)
OwnerId 上有一个索引。运行上述查询在不到 1 秒的时间内返回结果 (600)。但是,正如所指出的,该参数是可选的(以及其他参数),只要我稍微更改它以包含该值(如果不是 NULL)(我相信这是这样做的),相同的搜索就会超过 10 秒。
SET @OwnerId = 'A123456'
SELECT DISTINCT
t1.Id,
t2.OwnerId,
FROM
table1 t1
INNER JOIN [table2] t2 ON t1.Id = t2.id
WHERE
(@OwnerId IS null OR (t2.OwnerId = @OwnerId))
Run Code Online (Sandbox Code Playgroud)
我无法在生产服务器上运行执行计划,但在开发服务器上运行时可以看到略有不同(这没有 400 万行),所以有些事情正在发生变化,但不确定是什么。
我有一个SP,它有一个非常复杂的SQL语句,我需要能够将某些列与NULL进行比较,例如
...
FROM Categories
WHERE PID = @parentID
Run Code Online (Sandbox Code Playgroud)
@parentID是一个SP参数,可以是有效的NULL.
PID(父ID)uniqueidentifier也可以是有效的NULL(顶级类别).我可以使用,SET ANSI_NULLS OFF但文档说:
在SQL Server的未来版本中,ANSI_NULLS将始终为ON,并且将选项明确设置为OFF的任何应用程序都将生成错误.避免在新的开发工作中使用此功能,并计划修改当前使用此功能的应用程序.
什么可以是一个优雅的方式,而不是与重复相同的查询(S)IS NULL的情况下@parentID=NULL(也不能使用动态SQL):
IF @parentID IS NULL
SELECT...WHERE PID IS NULL
ELSE
SELECT...WHERE PID = @parentID
Run Code Online (Sandbox Code Playgroud)
编辑:我想避免一个IF因为我讨厌重复(巨大)代码.