web-dev-qa-db-ja.com

Sybaseデータベースのすべてのテーブルのすべての列を検索する

Micros Point of Salesシステムからデータをプルするアプリケーションを作成するというタスクに私は課税されています。 POSは、サーバーの1つで実行されているSybaseデータベースを使用しています。データベーススキーマは非常に複雑です。必要なデータにアクセスするために、ほとんどのスキーマを理解することができましたが、まだ見つかっていないことがいくつかあります。私は実際のPOSでそれらが何と呼ばれるかを知っていますが、データベース内のどこにもそれらを見つけることができません(ただし、実際には200以上のテーブルすべてを調べたわけではありません)。

すべてのテーブルのすべての列で特定の文字列を検索するクエリを実行する方法があるかどうか疑問に思っています。ところで、私はデータベースに接続するために、Sybase Database Clientソフトウェアに付属している「Interactive SQL」アプリケーションを使用しています。

2
Harry Muscle

私は最近同様の仕事をするように命じられていました。特にSybaseASEではITは簡単ではありません。

オプション1 :

ファイル内のデータをBCPで出力するカスタムツールを作成し、それらのファイルをgrepして、探したい特定のテキストを検索できます。 Perl正規表現を使用して同様に実行するか、ネイティブのUnix/Linuxコマンドを使用してこれらのファイルを解析し、検索する必要なテキストを見つけることができます。

オプション2:

別のオプション(TSQLを使用したそれほど速くて汚い方法ではありません)が私にとってはうまくいきました。

:これには長い時間(遅い、最適化されていない)が必要です。データベースのサイズ、ハードウェア、サーバーで実行されているワークロード、およびデータベースのレイアウトによって異なります。

テスト、テスト、事前にテスト!!

--- run below script and copy the output and run it in another query window.
set nocount on
declare @searchvalue varchar(255)
select @searchvalue = "test string to search"---- replace this .. !!
print "set nocount on"
print "go"
print "create table #results (table_name sysname, column_name sysname)"
print "go"

select
   "insert #results select distinct '"
   + object_name(c.id)
   + "' as table_name, '"
   + c.name
   + "' as column_name from "
   + object_name(c.id)
   + " where "
   + c.name
   + " LIKE '%"
   + @searchvalue
   + "%'"
   + char(10)
   + "go"
from
   syscolumns c, sysobjects o
where
   c.usertype in (
-- only look for char, varchar, text etc datatypes as we are not interested in int, datetime etc....
    1
    ,2
    ,18
    ,19
    ,24
    ,25
    ,42
    )
and o.type ='U' -- only user tables we are interested in
and c.id = o.id
and c.length>=datalength(@searchvalue )
--and object_name(c.id) = 'some table if you want to filter'

print "select * from #results"
print "go"
go
2
Kin Shah

次のようなクエリを実行できます。

Select o.name as table, c.name as column from syscolumns c, sysobjects o
Where c.id = o.id and
c.name like "stringImLookingFor"

最初の名前はテーブル名で、2番目の名前は列名です。探している正確な名前がわからない場合は、ワイルドカードとして「%」を使用できます。

0
Michael Gardner

データベースをテキストとしてディスクにダンプすることが実用的である場合は、通常のテキストユーティリティを使用してダンプを検索できます。 grepはあなたの友達です。

このためのスクリプトを作成し、検索文字列を含むすべてのTableNames、ColumnNamesを出力しました。

パフォーマンスが最適化されていません!!!カーソルを使用して関連する列をループするため、これを任意のDBで実行しても意味がありません(サイズ、テーブル/列の数などによって異なります)。

ただし、1回限りの検索では、DB内の文字列を見つけるのに便利なユーティリティです。

-----------------------------------------------------------------------------------------------------
-- SYBASE - SCRIPT TO FIND STRING IN ANY COLUMN IN TABLE AND PRINT TableName/ColumnName TO RESULTS --
-----------------------------------------------------------------------------------------------------

-- tested on Sybase ASE 15.7

set nocount off

-- CREATE OBJECTS REQUIRED FOR SCRIPT
create table #SearchString (SearchString varchar(100))
go

-- SET SEARCH STRING
declare @search_string  varchar(100)
set @search_string = 'SEARCH_STRING'

-- WRITE SEARCH STRING TO TEMP TABLE TO STORE IT AWAY AND BE ABLE TO READ IT IN NEXT BATCH
insert into #SearchString (SearchString)
    values (@search_string)

-- GET ALL RELEVANT TABLES AND COLUMNS
insert #TabCol
    select object_name(o.id) as TableName, c.name as ColumnName
        from sysobjects o, syscolumns c 
    where o.type = 'U' -- ONLY USER TABLES
          and c.usertype in (1,2,18,19,24,25,42) -- ONLY LOOK FOR CHAR, VARCHAR, ETC.
          and c.id = o.id
          and c.name is not null
          and c.length >= datalength(@search_string)
go

-- GET TOTAL NUMBER OF RELEVANT COLUMNS
select count(*) as ColumnsToLoopThrough from #TabCol
go

-- CREATE CURSOR TO LOOP THROUGH TABLES AND COLUMNS TO FIND COLUMNS CONTAINING THE SEARCH STRING
declare cur cursor for 
select TableName, ColumnName from #TabCol order by TableName, ColumnName
for read only
go

-- VARIABLE DEFINITION
declare
    @table_name     SYSNAME,
    @table_id       int,
    @column_name    SYSNAME,
    @sql_string     varchar(2000),
    @search_string  varchar(100)

-- GET SEARCH STRING FROM TABLE
select @search_string = SearchString from #SearchString

-- CURSOR INIT
open cur

fetch cur into @table_name, @column_name

-- LOOP THROUGH TABLES AND COLUMNS SEARCHING FOR SEARCH STRING AND PRINT IF FOUND
while (@@sqlstatus != 2)
begin
    set @sql_string = 'if exists (select * from ' + @table_name + ' where [' + @column_name + '] like ''%' + @search_string + '%'') print ''' + @table_name + ', ' + @column_name + ''''
    execute(@sql_string)
    fetch cur into @table_name, @column_name
end
go

-- CLEAN-UP
close cur
deallocate cur

drop table #SearchString
drop table #TabCol
go

乾杯

0
Remo