我想创建一个称为错误的视图,该视图是从另一个包含条件的“设置”表中馈送的。
设置表将有两列,如下所示:
+------------------------+--------------------------------------------------+
| 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+但也可以使用各种选项的解决方案。
答案 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 = ''