我有一个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会给我错误信息"'返回'""''' :
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
我不确定我做错了什么......
答案 0 :(得分:2)
语法上的第一步就是添加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