将SQL case语句转换为存储过程?
我有一个非常大的脚本,它正在创建多个视图。在许多视图中,都使用了相同的脚本。下面列出了该脚本将SQL case语句转换为存储过程?,sql,function,case,Sql,Function,Case,我有一个非常大的脚本,它正在创建多个视图。在许多视图中,都使用了相同的脚本。下面列出了该脚本 CASE WHEN pc.[user_name] IN ( SELECT [user_name] FROM people AS p WITH(NOLOCK) WHERE p.status_id = 1 p.last_login > DATEADD(MONTH, -12, GETDATE()) AND p.[user_name] NOT IN (
CASE WHEN pc.[user_name] IN
(
SELECT [user_name]
FROM people AS p WITH(NOLOCK)
WHERE p.status_id = 1 p.last_login > DATEADD(MONTH, -12, GETDATE())
AND p.[user_name] NOT IN
(
SELECT p.[user_name]
FROM people AS p WITH(NOLOCK)
WHERE p.status_id IN (1,2) AND p.[user_name] LIKE '%2'
)
) THEN pc.[user_name]
ELSE 'standarduser' END AS created_by
有人能告诉我如何编写一个函数的正确方向吗?在这个函数中,我可以传入
pc.[user\u name]
并返回正确的值?我不熟悉SQL中的函数。谢谢。您可以尝试这样的标量值函数
CREATE function [dbo].[MyFunction] (
@UserName nvarchar
)
returns nvarchar
as
begin
CASE WHEN pc.[user_name] IN
(
SELECT [user_name]
FROM people AS p WITH(NOLOCK)
WHERE p.status_id = 1 p.last_login > DATEADD(MONTH, -12, GETDATE())
AND p.[user_name] NOT IN
(
SELECT p.[user_name]
FROM people AS p WITH(NOLOCK)
WHERE p.status_id IN (1,2) AND p.[user_name] LIKE '%2'
)
)
THEN pc.[user_name] ELSE 'standarduser' END AS created_by
end
GO
编辑:
哦,假设您使用的SQL Server是,您可以将其作为视图或表函数(如果您需要其他逻辑或希望传入参数),并将其包含在像表一样连接的其他视图/过程中
;
with users as (
select p.user_name
, p.status_id
, p.last_login
from people as p with(nolock)
where p.status_id IN (1,2)
)
select DISTINCT u.user_name
, CASE WHEN u.[user_name] IN
(
SELECT [user_name]
FROM users AS u1
WHERE u1.status_id = 1 u1.last_login > DATEADD(MONTH, -12, GETDATE())
AND u1.[user_name] NOT IN
(
SELECT u2.[user_name]
FROM users AS u2
WHERE u2.status_id IN (1,2) AND u2.[user_name] LIKE '%2'
)
) THEN u.[user_name]
ELSE 'standarduser' END AS created_by
from users as u
可按如下方式创建该函数:
CREATE FUNCTION [dbo].[FunctionName] (@UserName VARCHAR(50))
RETURNS VARCHAR(50)
AS
BEGIN
RETURN COALESCE(
( SELECT [User_name]
FROM people AS p WITH(NOLOCK)
WHERE p.status_id = 1
AND p.last_login > DATEADD(MONTH, -12, GETDATE())
AND p.[user_name] NOT LIKE '%2'
AND [User_name] = @UserName
), 'StandardUser')
END
基于用户名是唯一的假设,我已尝试尽可能简化您的选择,即用户名的状态ID不能同时为1和2,这允许我从语句中删除不在中,首先选择一组状态为1的用户,然后从中删除状态为1或2且用户名以2结尾的用户。由于第一个组中没有任何人的status_ID为1,因此您可以删除第一个组中用户名以2结尾的人,这不需要子查询,只需要一个where子句
尽管如此,我仍然倾向于使用视图或类似的基于集合的解决方案来实现相同的结果。比如:
SELECT *, COALESCE(a.[User_Name], 'StandardUser') [NewUserName]
FROM People p
LEFT JOIN
( SELECT [User_name]
FROM people AS p WITH(NOLOCK)
WHERE p.status_id = 1
AND p.last_login > DATEADD(MONTH, -12, GETDATE())
AND p.[user_name] NOT LIKE '%2'
) a
ON p.[User_name] = a.[User_name]
哇!如果您最终在结果集中使用此函数,您的查询将会很慢…您是否有任何可以检查的主键而不是用户名?旁注:您可以将子查询替换为NOT(p.status\u id in(1,2)和p.[user\u name]如“%2”)
。谢谢您的评论。非常感谢您的帮助!我正在使用SQL Server。我正在将用户从旧系统迁移到新系统,因此无法使用主键@Pablo:一个非常有建设性的评论…我同意上面的评论,我只是复制并粘贴了你的查询到一个函数中。一旦您的选定零件开始工作,您应该将[user\u name]切换为[user\u id]或该表的任何id。在“in”列表中检查int会更有效率谢谢你的反馈Gareth。使用您给出的建议,我希望能够缩短查询时间。您认为使用视图或函数更好吗?如果性能有问题,请避免使用标量函数,而使用表函数。视图。一般来说,如果可能的话,我尽量避免使用标量函数。它们没有得到很好的优化,与基于集合的解决方案相比,您会注意到使用UDF会显著降低性能。即使是最简单的udf也可以很好地演示如何影响性能。