Sql server 基于SQL参数返回具有不同列的表
我正在编写一个存储过程,它根据用户角色运行不同的选择,这只是一个示例来展示我的意图,因为我有很多角色要处理Sql server 基于SQL参数返回具有不同列的表,sql-server,stored-procedures,Sql Server,Stored Procedures,我正在编写一个存储过程,它根据用户角色运行不同的选择,这只是一个示例来展示我的意图,因为我有很多角色要处理 IF OBJECT_ID('dbo.spSelectArtigos') IS NOT NULL DROP PROCEDURE spSelectArtigos GO CREATE PROCEDURE spSelectArtigos @IdUser int, @Acesso nvarchar(20) AS BEGIN IF(@Acesso = 'User')
IF OBJECT_ID('dbo.spSelectArtigos') IS NOT NULL
DROP PROCEDURE spSelectArtigos
GO
CREATE PROCEDURE spSelectArtigos
@IdUser int,
@Acesso nvarchar(20)
AS
BEGIN
IF(@Acesso = 'User')
SELECT col1,col2 from table1 where IdUser = @IdUser
IF(@Acesso = 'Logistica')
SELECT col1,col2,col3 from table1 where IdUser = @IdUser
IF(@Acesso = 'Admin')
SELECT * From table1
END
有没有一种更有效的方法可以用更少的代码使用某种逻辑来实现这一点?IDK为什么我添加了一个检查来确保用户确实存在,但这不是一个坏主意
IF OBJECT_ID('dbo.spSelectArtigos') IS NOT NULL
DROP PROCEDURE spSelectArtigos
GO
CREATE PROCEDURE spSelectArtigos
@IdUser int,
@Acesso nvarchar(20)
AS
BEGIN
CASE
WHEN @Acesso ='User'
AND
EXISTS (SELECT * FROM table1 WHERE IdUser = @IdUser)
THEN
SELECT col1,col2 from table1 where IdUser = @IdUser
WHEN @Acesso ='Logistica' Then
AND
EXISTS (SELECT * FROM table1 WHERE IdUser = @IdUser)
THEN
SELECT col1,col2,col3 from table1 where IdUser = @IdUser
WHEN @Acesso ='Admin'
AND
EXISTS (SELECT * FROM table1 WHERE IdUser = @IdUser)
THEN
SELECT * From table1
END
END
IDK为什么我添加了一个检查,以确保用户确实存在,但这不是一个坏主意
IF OBJECT_ID('dbo.spSelectArtigos') IS NOT NULL
DROP PROCEDURE spSelectArtigos
GO
CREATE PROCEDURE spSelectArtigos
@IdUser int,
@Acesso nvarchar(20)
AS
BEGIN
CASE
WHEN @Acesso ='User'
AND
EXISTS (SELECT * FROM table1 WHERE IdUser = @IdUser)
THEN
SELECT col1,col2 from table1 where IdUser = @IdUser
WHEN @Acesso ='Logistica' Then
AND
EXISTS (SELECT * FROM table1 WHERE IdUser = @IdUser)
THEN
SELECT col1,col2,col3 from table1 where IdUser = @IdUser
WHEN @Acesso ='Admin'
AND
EXISTS (SELECT * FROM table1 WHERE IdUser = @IdUser)
THEN
SELECT * From table1
END
END
这里有一个含糊不清的方式,但它是简洁的
IF OBJECT_ID('dbo.spSelectArtigos') IS NOT NULL
DROP PROCEDURE spSelectArtigos
GO
CREATE PROCEDURE spSelectArtigos
@IdUser int,
@Acesso nvarchar(20)
AS
BEGIN
DECLARE @Result TABLE(A INT,B INT,C INT,D INT)
INSERT @Result SELECT A,B,C,D FROM table1 WHERE idUser=@idUser
IF(@Acesso = 'User')
UPDATE @Result SET C=NULL, D=NULL
IF(@Acesso = 'Logistica')
UPDATE @Result SET D=NULL
SELECT * From @Result
END
另一种处理身份证的方法
SELECT
A=CASE WHEN @Acesso >= 10 THEN A ELSE NULL END,
B=CASE WHEN @Acesso >= 20 THEN B ELSE NULL END,
C=CASE WHEN @Acesso >= 99 THEN C ELSE NULL END
FROM
table1
WHERE
idUser=@idUser
这里有一个含糊不清的方式,但它是简洁的
IF OBJECT_ID('dbo.spSelectArtigos') IS NOT NULL
DROP PROCEDURE spSelectArtigos
GO
CREATE PROCEDURE spSelectArtigos
@IdUser int,
@Acesso nvarchar(20)
AS
BEGIN
DECLARE @Result TABLE(A INT,B INT,C INT,D INT)
INSERT @Result SELECT A,B,C,D FROM table1 WHERE idUser=@idUser
IF(@Acesso = 'User')
UPDATE @Result SET C=NULL, D=NULL
IF(@Acesso = 'Logistica')
UPDATE @Result SET D=NULL
SELECT * From @Result
END
另一种处理身份证的方法
SELECT
A=CASE WHEN @Acesso >= 10 THEN A ELSE NULL END,
B=CASE WHEN @Acesso >= 20 THEN B ELSE NULL END,
C=CASE WHEN @Acesso >= 99 THEN C ELSE NULL END
FROM
table1
WHERE
idUser=@idUser
您应该签出大小写表达式:。在没有深入研究的情况下不要使用动态SQL。我甚至建议您编写特定于角色的存储过程,这些存储过程被调用,而不是单个SELECT语句。这样,当特定角色的规则更改时,您只需更新相应的过程。另外,使用
SELECT*
有一种非常糟糕的代码味道。哦,我知道这只是我写的一个简单的例子,因为我的查询有很多连接,而且太长,无法在这里发布。根据输入参数返回不同结果“形状”的存储过程可能非常棘手(或者几乎不可能)当试图将它们与类似ORM的实体框架或Dapper一起使用时。我建议不要这样做—如果您有三种不同类型的用户角色—创建三个单独的存储过程,每个任务一个存储过程(遵循“单一责任原则”)—这也会使维护更容易!您应该签出大小写表达式:。在没有深入研究的情况下不要使用动态SQL。我甚至建议您编写特定于角色的存储过程,这些存储过程被调用,而不是单个SELECT语句。这样,当特定角色的规则更改时,您只需更新相应的过程。另外,使用SELECT*
有一种非常糟糕的代码味道。哦,我知道这只是我写的一个简单的例子,因为我的查询有很多连接,而且太长,无法在这里发布。根据输入参数返回不同结果“形状”的存储过程可能非常棘手(或者几乎不可能)当试图将它们与类似ORM的实体框架或Dapper一起使用时。我建议不要这样做—如果您有三种不同类型的用户角色—创建三个单独的存储过程,每个任务一个存储过程(遵循“单一责任原则”)—这也会使维护更容易!状态很好,道格。不确定它可能包含什么,但我建议使用ELSE
块返回一些内容,以便不在任何枚举角色中的人获得某种结果集(即使它是选择CAST(NULL为INT)作为NoCol,其中1=2
),如果不希望没有这些角色的UID看到任何内容,该怎么办?OP不太具体,你不应该提供超过必要的内容,尤其是在可见性方面。最糟糕的事情是,一个粗声粗气的工人看到了首席执行官的仪表盘。极端,是的,但你得到了平塔公平点。信任客户端代码处理空的结果集(与有结构但没有数据的结果集相比)?这里引用了多个主题/透视图。简单地说,我是按照给定的标准工作的。抽象地说,你不能总是计算代码打嗝。有时由于某些原因网页或表单做得不好。多层并不总是坏事好表单,道格。不确定它可能包含什么,但我建议使用ELSE
块返回一些内容,以便不在任何枚举角色中的人获得某种结果集(即使它是选择CAST(NULL为INT)作为NoCol,其中1=2
),如果不希望没有这些角色的UID看到任何内容,该怎么办?OP不太具体,你不应该提供超过必要的内容,尤其是在可见性方面。最糟糕的事情是,一个粗声粗气的工人看到了首席执行官的仪表盘。极端,是的,但你得到了平塔公平点。信任客户端代码处理空的结果集(与有结构但没有数据的结果集相比)?这里引用了多个主题/透视图。简单地说,我是按照给定的标准工作的。抽象地说,你不能总是计算代码打嗝。有时由于某些原因,网页或表单做得不好。多层并不总是一件坏事