0

The Situation

I come from PHP + MySQL background and I'm migrating an ASP website.

I've migrated them a few times before, but in this case I'm encountering a couple of issues that disorient me and are preventing me from importing a database.

The Obstacles

  1. I downloaded, through Plesk (current version as of writing of this post), a backup of the MS SQL database. But upon opening it I find strings of numbers, not SQL. Thus I cannot do a find and replace of the website URL.

Ex.

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. When I connect to MS SQL via myLittleAdmin and navigate to Tools > New Query and attempt to use a FIND or SEARCH command, as I would in MySQL, it simply doesn't work.

I search the MS SQL documention for similar commands but couldn't locate any. And all of the Questions here on Stack Overflow that come up related to my question have huge queries that have a lot of syntax / code that is irrelevant to the simplicity of my question.

The Question

Can someone help me understand what I'm missing here?

Ultimately I am just seeking the MS SQL code I write to search the entire database for an instance of a particular string of text.

Spencer Hill
  • 1,043
  • 2
  • 15
  • 38
  • Query the system tables to find all char, nchar, varchar, and nvarchar columns. Loop through the results looking for your string. – Dan Bracuk Jun 05 '17 at 03:12
  • Thanks for the reply but I mentioned in the post I don't know what to write. I'm happy to learn how to write it but I need some direction because the official docs didn't return any results for searching functions. I'm sure I probably just don't have the right term when I'm looking through the docs. – Spencer Hill Jun 05 '17 at 03:16
  • 2
    A SQL Server **backup** (`.bak`) is a **binary file** - not SQL commands. You need to use the SQL Server `RESTORE` command to restore it - you cannot just peek inside it – marc_s Jun 05 '17 at 06:17
  • Juts to clarify for all - a MySql backup is a text dump of the DML and DDL that makes up a database. @SpencerHill Sql Server backups are totally and utterly different in every conceivable respect and, as marc_s said above, are stored in a non modifiable binary format that can ONLY be used in a subsequent restore. – Rachel Ambler Jun 05 '17 at 11:04
  • Ah, okay, hence the strings of numbers. Thank you for clarifying! I didn't know the SQL Server was that different from MySQL and it's respectful .sql files which are human readable. Thank you. – Spencer Hill Jun 05 '17 at 17:04
  • @marc_s, I saw your edits to the post and decided to roll back because - although I understand you're edits implied there is no such thing as "MS SQL", I spent a lot of time searching for that phrase so hopefully others that do the same will find this post and learn. Thanks for the edits though that helped me! – Spencer Hill Jun 05 '17 at 17:07
  • @SpencerHill: it's your question, and I can't really force you to use the **proper, official** product name .... if you **insist** on using the wrong, unofficial name - your call. But now everyone trying to find your question using the **proper, official product name** will not be able to find it ...... but again: it's your call ..... – marc_s Jun 05 '17 at 20:31
  • So I've done some more research and found official references to MS SQL both on Microsoft's website and within Plesk. Why would that be? – Spencer Hill Jun 06 '17 at 20:36
  • Possible duplicate of [Search for a string across all the databases in SQL SERVER and list all the databases, tables and corresponding columns](https://stackoverflow.com/questions/43855563/search-for-a-string-across-all-the-databases-in-sql-server-and-list-all-the-data) –  Jun 07 '17 at 17:05

2 Answers2

0

Please see the following SO post on obtaining a dump: How can I get a SQL dump of a SQL Server 2008 database?

From there, locate the text in question then update the actual DB accordingly once you've identified the requisite tables and columns.

Rachel Ambler
  • 1,440
  • 12
  • 23
  • Thanks Amber, I'll give this a shot and mark this as the answer assuming I'm successful following whatever instructions are in that article. – Spencer Hill Jun 05 '17 at 17:09
  • Hi Amber, for some reason I'm unable to remotely connect using Microsoft SQL Server Manager so I'm unable to export the database into the proposed readable format. However, I can run a query. My original question was actually asking what the query is to search the entire database. Are you able to help me with that? Thank you! – Spencer Hill Jun 06 '17 at 20:38
0

I hired someone to write the script for me.

Here is the find script (update line 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

And here is the find and replace script (update line 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
Spencer Hill
  • 1,043
  • 2
  • 15
  • 38