我有一个 SQL 查询,在大多数情况下,它会返回字符串的位置,无论它出现在给定数据库中的哪个位置。
我想将其转换为 SQL 中的一个函数,但我没有足够的函数经验(阅读:任何经验)并且在这样做时遇到了麻烦。
/* Set @SearchStr to a string you are looking for and all text columns of a DB
will be searched to find that string */
DECLARE @sql nvarchar(4000)
DECLARE @SearchStr nvarchar(100)
SET @SearchStr = 'TYPE What you are looking for here'
DECLARE @Results TABLE (
TableName nvarchar(256)
, ColumnName nvarchar(370)
, ColumnValue nvarchar(3630)
)
SET NOCOUNT ON
DECLARE @TableName nvarchar(256)
, @ColumnName nvarchar(128)
, @SearchStr2 nvarchar(110)
SET @TableName = ''
SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%', '''')
WHILE @TableName IS NOT NULL
BEGIN
SET @ColumnName = ''
SET @TableName = (SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName
AND OBJECTPROPERTY(OBJECT_ID(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)),
'IsMSShipped') = 0)
WHILE (@TableName IS NOT NULL)
AND (@ColumnName IS NOT NULL)
BEGIN
SET @ColumnName = (SELECT MIN(QUOTENAME(COLUMN_NAME))
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = PARSENAME(@TableName, 2)
AND TABLE_NAME = PARSENAME(@TableName, 1)
AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar')
AND QUOTENAME(COLUMN_NAME) > @ColumnName)
IF @ColumnName IS NOT NULL
BEGIN
SET @sql = 'SELECT TableName = ''' + @TableName + ''', ''' + @TableName + '.' + @ColumnName
+ ''', LEFT(' + @ColumnName + ', 3630)
FROM ' + @TableName + ' (NOLOCK) ' + 'WHERE ' + @ColumnName
+ ' LIKE ' + @SearchStr2
--PRINT @sql
INSERT INTO @Results
EXECUTE (@sql
)
END
END
END
SELECT * FROM @Results
我试图将它变成“创建函数”语句,但我总是在某处遇到语法错误。
这是我用这个做的最远的一次,我执行这个 SQL 会给我错误消息“'Return' 附近的语法无效”:
create function dbo.FindString( @SearchStr Varchar(256) )
RETURNS
@Results TABLE (
TableName nvarchar(256)
, ColumnName nvarchar(370)
, ColumnValue nvarchar(3630)
)
AS
BEGIN
DECLARE @sql nvarchar(4000)
--DECLARE @SearchStr nvarchar(100)
SET @SearchStr = ''
SET NOCOUNT ON
DECLARE @TableName nvarchar(256)
, @ColumnName nvarchar(128)
, @SearchStr2 nvarchar(110)
SET @TableName = ''
SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%', '''')
WHILE @TableName IS NOT NULL
BEGIN
SET @ColumnName = ''
SET @TableName = (SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName
AND OBJECTPROPERTY(OBJECT_ID(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)),
'IsMSShipped') = 0)
WHILE (@TableName IS NOT NULL)
AND (@ColumnName IS NOT NULL)
BEGIN
SET @ColumnName = (SELECT MIN(QUOTENAME(COLUMN_NAME))
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = PARSENAME(@TableName, 2)
AND TABLE_NAME = PARSENAME(@TableName, 1)
AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar')
AND QUOTENAME(COLUMN_NAME) > @ColumnName)
IF @ColumnName IS NOT NULL
BEGIN
SET @sql = 'SELECT TableName = ''' + @TableName + ''', ''' + @TableName + '.' + @ColumnName
+ ''', LEFT(' + @ColumnName + ', 3630)
FROM ' + @TableName + ' (NOLOCK) ' + 'WHERE ' + @ColumnName
+ ' LIKE ' + @SearchStr2
--PRINT @sql
INSERT INTO @Results
EXECUTE (@sql
)
END
END
END
Return
我不确定我做错了什么......
最佳答案
语法上的第一步只是添加一个 end
作为脚本的最后一行,以与第一个 begin
配对。不幸的是,那时您会收到关于在函数内使用 set nocount on
和 exec
的投诉。其中第一个没有问题,但第二个是个问题。
由于您不能在函数内部使用动态 sql,您的下一个最佳选择是存储过程,这里只需要进行一些小手术。第一步是将定义更改为过程,从下面的行开始替换所有内容,直到初始 as
并包括整个 returns @results
部分。
create procedure dbo.FindString @SearchStr Varchar(256) as
最后的调整是将 return
更改为 select * from @Results
。
确保在将其用作较长脚本的一部分之前和之后在单独的行中添加 go
。 create procedure
必须显示为它自己的单独批处理。使用 exec dbo.FindString 'test'
进行尝试。
https://msdn.microsoft.com/en-us/library/ms187926.aspx
创建这个存储过程的SQL:
create procedure dbo.FindString( @SearchStr Varchar(256) )
AS
BEGIN
DECLARE @sql nvarchar(4000)
--DECLARE @SearchStr nvarchar(100)
--SET @SearchStr = ''
DECLARE @Results TABLE (
TableName nvarchar(256)
, ColumnName nvarchar(370)
, ColumnValue nvarchar(3630)
)
--SET NOCOUNT ON
DECLARE @TableName nvarchar(256)
, @ColumnName nvarchar(128)
, @SearchStr2 nvarchar(110)
SET @TableName = ''
SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%', '''')
WHILE @TableName IS NOT NULL
BEGIN
SET @ColumnName = ''
SET @TableName = (SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName
AND OBJECTPROPERTY(OBJECT_ID(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)),
'IsMSShipped') = 0)
WHILE (@TableName IS NOT NULL)
AND (@ColumnName IS NOT NULL)
BEGIN
SET @ColumnName = (SELECT MIN(QUOTENAME(COLUMN_NAME))
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = PARSENAME(@TableName, 2)
AND TABLE_NAME = PARSENAME(@TableName, 1)
AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar')
AND QUOTENAME(COLUMN_NAME) > @ColumnName)
IF @ColumnName IS NOT NULL
BEGIN
SET @sql = 'SELECT TableName = ''' + @TableName + ''', ''' + @TableName + '.' + @ColumnName
+ ''', LEFT(' + @ColumnName + ', 3630)
FROM ' + @TableName + ' (NOLOCK) ' + 'WHERE ' + @ColumnName
+ ' LIKE ' + @SearchStr2
--PRINT @sql
INSERT INTO @Results
EXECUTE (@sql
)
END
END
END
SELECT * FROM @Results
END
关于sql - 将 SQL 查询转化为函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39176550/