【问题标题】:How do you search MS SQL database for a particular string?如何在 MS SQL 数据库中搜索特定字符串?
【发布时间】:2017-06-08 01:04:27
【问题描述】:

情况

我来自 PHP + MySQL 背景,我正在迁移一个 ASP 网站。

我之前已经迁移了几次,但在这种情况下,我遇到了一些让我迷失方向并阻止我导入数据库的问题。

障碍

  1. 我通过 Plesk(撰写本文时的当前版本)下载了 MS SQL 数据库的备份。但是在打开它时,我发现一串数字,而不是 SQL。因此,我无法查找和替换网站 URL。

例如

5441 5045 0000 0300 8c00 0e01 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000

  1. 当我通过 myLittleAdmin 连接到 MS SQL 并导航到工具 > 新查询并尝试使用 FINDSEARCH 命令时,就像在 MySQL 中一样,它根本不起作用。

我在 MS SQL 文档中搜索类似的命令,但找不到任何命令。 Stack Overflow 上与我的问题相关的所有问题都有大量的查询,其中包含很多与我的问题的简单性无关的语法/代码。

问题

有人可以帮助我了解我在这里缺少什么吗?

最终,我只是在寻找我编写的 MS SQL 代码,以在整个数据库中搜索特定文本字符串的实例。

【问题讨论】:

  • 查询系统表以查找所有 char、nchar、varchar 和 nvarchar 列。循环查找您的字符串的结果。
  • 感谢您的回复,但我在帖子中提到我不知道该写什么。我很高兴学习如何编写它,但我需要一些指导,因为官方文档没有返回任何搜索功能的结果。我确定我在查看文档时可能只是没有正确的术语。
  • A SQL Server backup (.bak) 是一个二进制文件 - 不是 SQL 命令。你需要使用 SQL Server RESTORE 命令来恢复它 - 你不能只是窥视它
  • 澄清一下——MySql 备份是组成数据库的 DML 和 DDL 的文本转储。 @SpencerHill Sql Server 备份在每个可以想象的方面都完全不同,并且正如上面所说的 marc_s,以不可修改的二进制格式存储,只能在后续恢复中使用。
  • 啊,好吧,因此是数字字符串。谢谢你的澄清!我不知道 SQL Server 与 MySQL 有什么不同,它尊重人类可读的 .sql 文件。谢谢。

标签: sql-server


【解决方案1】:

请参阅以下关于获取转储的 SO 帖子:How can I get a SQL dump of a SQL Server 2008 database?

从那里找到有问题的文本,然后在您确定必要的表和列后相应地更新实际数据库。

【讨论】:

  • 谢谢 Amber,我会试一试并将其标记为答案,假设我按照该文章中的任何说明成功。
  • 您好 Amber,由于某种原因,我无法使用 Microsoft SQL Server Manager 进行远程连接,因此无法将数据库导出为建议的可读格式。但是,我可以运行查询。我最初的问题实际上是询问搜索整个数据库的查询是什么。你能帮我解决这个问题吗?谢谢!
【解决方案2】:

我雇了人为我写剧本。

这是find 脚本(更新第 2 行,“TEXT_TO_SEARCH”):

USE DATABASE_NAME
DECLARE @SearchStr nvarchar(100) = 'TEXT_TO_SEARCH'
DECLARE @Results TABLE (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', 'int', 'decimal')
                AND    QUOTENAME(COLUMN_NAME) > @ColumnName
        )

        IF @ColumnName IS NOT NULL

        BEGIN
            INSERT INTO @Results
            EXEC
            (
                'SELECT ''' + @TableName + '.' + @ColumnName + ''', LEFT(' + @ColumnName + ', 3630) 
                FROM ' + @TableName + ' (NOLOCK) ' +
                ' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2
            )
        END
    END    
END

SELECT ColumnName, ColumnValue FROM @Results

这里是 find and replace 脚本(更新第 13 行):

SET NOCOUNT ON 

DECLARE @stringToFind VARCHAR(100) 
DECLARE @stringToReplace VARCHAR(100) 
DECLARE @schema sysname 
DECLARE @table sysname 
DECLARE @count INT 
DECLARE @sqlCommand VARCHAR(8000) 
DECLARE @where VARCHAR(8000) 
DECLARE @columnName sysname 
DECLARE @object_id INT 

SET @stringToFind = 'TEXT_TO _FIND'
SET @stringToReplace = 'TEXT_TO_REPLACE' 

DECLARE TAB_CURSOR CURSOR  FOR 
SELECT   B.NAME      AS SCHEMANAME, 
         A.NAME      AS TABLENAME, 
         A.OBJECT_ID 
FROM     sys.objects A 
         INNER JOIN sys.schemas B 
           ON A.SCHEMA_ID = B.SCHEMA_ID 
WHERE    TYPE = 'U' 
ORDER BY 1 

OPEN TAB_CURSOR 

FETCH NEXT FROM TAB_CURSOR 
INTO @schema, 
     @table, 
     @object_id 

WHILE @@FETCH_STATUS = 0 
  BEGIN 
    DECLARE COL_CURSOR CURSOR FOR 
    SELECT A.NAME 
    FROM   sys.columns A 
           INNER JOIN sys.types B 
             ON A.SYSTEM_TYPE_ID = B.SYSTEM_TYPE_ID 
    WHERE  OBJECT_ID = @object_id 
           AND IS_COMPUTED = 0 
           AND B.NAME IN ('char','nchar','nvarchar','varchar','text','ntext') 

    OPEN COL_CURSOR 

    FETCH NEXT FROM COL_CURSOR 
    INTO @columnName 

    WHILE @@FETCH_STATUS = 0 
      BEGIN 
        SET @sqlCommand = 'UPDATE ' + @schema + '.' + @table + ' SET [' + @columnName 
                           + '] = REPLACE(convert(nvarchar(max),[' + @columnName + ']),''' 
                           + @stringToFind + ''',''' + @stringToReplace + ''')' 

        SET @where = ' WHERE [' + @columnName + '] LIKE ''%' + @stringToFind + '%''' 

        EXEC( @sqlCommand + @where) 

        SET @count = @@ROWCOUNT 

        IF @count > 0 
          BEGIN 
            PRINT @sqlCommand + @where 
            PRINT 'Updated: ' + CONVERT(VARCHAR(10),@count) 
            PRINT '----------------------------------------------------' 
          END 

        FETCH NEXT FROM COL_CURSOR 
        INTO @columnName 
      END 

    CLOSE COL_CURSOR 
    DEALLOCATE COL_CURSOR 

    FETCH NEXT FROM TAB_CURSOR 
    INTO @schema, 
         @table, 
         @object_id 
  END 

CLOSE TAB_CURSOR 
DEALLOCATE TAB_CURSOR

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-21
    • 2018-05-25
    • 2023-03-07
    相关资源
    最近更新 更多