创建一个SQL视图来检查从另一个表提供的各种条件

时间:2018-10-23 00:31:23

标签: sql-server validation

我想创建一个称为错误的视图,该视图是从另一个包含条件的“设置”表中馈送的。

设置表将有两列,如下所示:

+------------------------+--------------------------------------------------+
|      Description       |                     Criteria                     |
+------------------------+--------------------------------------------------+
| Missing birth country  |  from stu where bcu = ''                         |
| Email invalid          |  from con where em not like '%@%.%' and em <> '' |
+------------------------+--------------------------------------------------+

错误视图看起来像是两列(注释ID是用于说明目的的学生ID,可以是任意数字)

+------+------------------------+
|  ID  |          Error         |
+------+------------------------+
| 123  |  Email invalid         |
| 123  |  Missing birth country |
| 234  |  Email invalid         |
+------+------------------------+
etc...

到目前为止,这是我对SQL View的了解。如何创建动态视图以从设置表中提取这些设置?

--missing birth country
select id,
'Missing birth country.' as err
from stu where bcu = '' and del = 0

union all

--invalid email format
select id,
'Email invalid format in Contacts' as err
from con where em not like '%@%.%' and em <> '' and del = 0

请注意,这是与MS SQL Server一起使用的,我更喜欢一种适用于2008+但也可以使用各种选项的解决方案。

2 个答案:

答案 0 :(得分:3)

这有效:

DECLARE @SQL NVARCHAR(max)

SET @SQL = N''

SELECT
    @SQL = @SQL + 'SELECT id, '''+ Description + ''' as err ' + Criteria +CHAR(13)+CHAR(10)+'UNION ALL'+CHAR(13)+CHAR(10)
FROM settings

SET @SQL = LEFT(@SQL, LEN(@SQL) - 11)
PRINT @SQL
EXEC sp_executesql @SQL

您可能应该通过转义Description字符串中的字符来改善它,但这是您问题的核心答案。


编辑:使用OP注释创建表函数并查看调用它的视图。

CREATE FUNCTION dbo.tvf_getErrors
   RETURNS  TABLE  AS

    (
     SELECT * FROM OPENROWSET('SQLNCLI', 'Server=localhost; Trusted_Connection=yes;', 'EXEC(N''sp_executesql N'''''' + ''SELECT ''''''''select '''''''' + pk + '''''''' as id, '''''''''''''''''''''''' + de + '''''''''''''''''''''''' as err '''''''' + CR + '''''''' UNION ALL'''''''' as sql FROM DVAS'''''' )')
    )
RETURN
GO

我根本无法检查所有的'是否都在那里...而且看起来更难看。现在,您要做的就是在视图内部引用此表值函数,如下所示:

CREATE VIEW dbo.v_getErrors 
AS 
SELECT * FROM dbo.tvf_getErrors()

执行此操作时,我意识到您可以省略使用表值函数并直接从视图中调用OpenRowSet,如下所示:

CREATE VIEW dbo.v_getErrors 
AS 
     SELECT * FROM OPENROWSET('SQLNCLI', 'Server=localhost; Trusted_Connection=yes;', 'EXEC(N''sp_executesql N'''''' + ''SELECT ''''''''select '''''''' + pk + '''''''' as id, '''''''''''''''''''''''' + de + '''''''''''''''''''''''' as err '''''''' + CR + '''''''' UNION ALL'''''''' as sql FROM DVAS'''''' )')

有。一旦找出所有撇号,就可以使用。

答案 1 :(得分:3)

创建这样的存储过程(我从@The_Player的代码获得帮助):

CREATE PROCEDURE [dbo].[testPrc]
AS
set nocount on
SET FMTONLY OFF
BEGIN
DECLARE @SQL NVARCHAR(max)

SET @SQL = N''

SELECT
@SQL = @SQL + 'SELECT id, '''+ Description + ''' as err ' + Criteria         +CHAR(13)+CHAR(10)+'UNION ALL'+CHAR(13)+CHAR(10)
FROM settings

SET @SQL = LEFT(@SQL, LEN(@SQL) - 11)
PRINT @SQL
EXEC sp_executesql @SQL

END  

运行以下命令:

EXEC sp_configure 'show advanced options', 1
RECONFIGURE
GO
EXEC sp_configure 'ad hoc distributed queries', 1
RECONFIGURE
GO  

创建视图:

CREATE VIEW [dbo].[testView]
AS
SELECT        ID, err
FROM            OPENROWSET('SQLNCLI', 'Server=localhost;Trusted_Connection=yes;', 
'exec TestDB.dbo.testPrc WITH RESULT SETS (  (    ID INT,   err VARCHAR(150)   )  ) 
') AS derivedtbl_1
GO  

编辑:
没有存储过程的第二种解决方案:

CREATE VIEW [dbo].[testView2]
AS
SELECT ID, err
FROM OPENROWSET('SQLNCLI', 'Server=localhost;Trusted_Connection=yes;', 
'EXECUTE sp_executesql   
N''SELECT
@SQL = @SQL + ''''SELECT id, ''''+''''''''''''''''+ Description +     ''''''''''''''''+'''' as err '''' + Criteria +CHAR(13)+CHAR(10)+''''UNION     ALL''''+CHAR(13)+CHAR(10)
FROM TestDB.dbo.settings
SET @SQL = LEFT(@SQL, LEN(@SQL) - 11)
EXEC sp_executesql @SQL
WITH RESULT SETS (  (    ID INT,   err VARCHAR(150)   )  ) 
'',  
N''@SQL NVARCHAR(max)'',  
@SQL = N'''' 
WITH RESULT SETS (  (    ID INT,   err VARCHAR(150)   )  )' ) AS     derivedtbl_1
GO  

只有几点
您应该在表名的开头添加数据库名和架构名。
例如:

from stu where bcu = ''  

应该是:

from TestDB.dbo.stu where bcu = ''