将SQL查询转换为函数

时间:2016-08-27 01:09:30

标签: sql sql-server function

我有一个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

我不确定我做错了什么......

1 个答案:

答案 0 :(得分:2)

语法上的第一步就是添加end作为脚本的最后一行,与第一个begin配对。不幸的是,您会收到有关在函数中使用set nocount onexec的投诉。第一个是没有汗,但第二个是问题。

由于您无法在函数内部使用动态SQL,因此您的下一个最佳选择是存储过程,此处只需要进行小手术。第一步是将定义更改为一个过程,从下面的行开始,将所有内容替换为最初的as并包括整个returns @results部分。

create procedure dbo.FindString @SearchStr Varchar(256) as

最后一项调整是将return更改为select * from @Results

确保在使用此作为较长脚本的一部分之前和之后的单独行上添加gocreate 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