MS SQL wyszukanie rekordu bazy danych

0

Witam,

na wstępie informuję że jestem laikiem jeżeli chodzi o bazę danych, mam następujący problem, posiadam dostęp do bazy danych poprzez Excela :) , w bazie znajdują się setki tabel a ja nie znam jej struktury, poszukuję tabeli w której znajduje się określona wartość rekordu, wielkość bazy jest olbrzymia, mogę poprzez aplikację sam wpisać jakieś niestandardowe dane w celu łatwoejszego znalezienia tego w bazie, muszę znelźć konkrentą tabelę w której zostanie wpisany ten rekord.

Pomoże ktoś ?

0

Da się to zrobić ale nie będzie to proste ... o ile możesz bez większych problemów pobrać listę tabel z bazy np tak:

SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE'

o tyle w kolejnych krokach będziesz musiał dla każdej tabeli z osobna wyszukać ich kolumny i (z tego co napisałeś) wybrać tylko te które są typu tekstowego
można np tak:

SELECT 
    c.name 'Column Name',
    t.Name 'Data type',
    c.max_length 'Max Length',
    c.precision ,
    c.scale ,
    c.is_nullable,
    ISNULL(i.is_primary_key, 0) 'Primary Key'
FROM    
    sys.columns c
INNER JOIN 
    sys.types t ON c.user_type_id = t.user_type_id
LEFT OUTER JOIN 
    sys.index_columns ic ON ic.object_id = c.object_id AND ic.column_id = c.column_id
LEFT OUTER JOIN 
    sys.indexes i ON ic.object_id = i.object_id AND ic.index_id = i.index_id
WHERE
    c.object_id = OBJECT_ID('tablename')

następnie bierzesz tą listę kolumn z danej tabeli i robisz zapytanie dynamiczne przez sp_executesql gdzie sprawdzasz wartość każdej kolumny z interesującą Ciebie wartością. Jak dataset zwróci jakąś wartość to masz znalezioną kolumnę i tabelę ... ogólnie dla kogoś kto zaczyna przygodę z bazami dość trudny temat bez odpowiednich pętli i przynajmniej podstawowej znajomości TSQL będzie ciężko ale da się.

No chyba, że ktoś ma lepszy pomysł wołam @Marcin.Miga

1
/****** Object:  StoredProcedure [dbo].[SearchAllTables2]    Script Date: 10/01/2015 16:08:09 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE PROC [dbo].[SearchAllTables2]
(
    @SearchStr nvarchar(100)
)
AS
BEGIN

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')
                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
END
GO

sprawdzone i przydatne

0

Wywołany czuję się zobligowany, by odpowiedzieć.
Oba podane powyżej sposoby bazują na tym samym - information_schema.tables. Lepszego sposobu chyba nie ma. Ale trzeba mieć dostęp do bazy. Bezpośredni, nie przez Excela
W samym Excelu można wyszukać przez Znajdź, szukaj w "Skoroszyt" zamiast "arkusz"... Tyle, że samo wyszukiwanie w Excelu trochę kuleje...

0

Moim zdaniem masz 2 możliwości, skoro przez Excela masz dostęp to równie dobrze masz ten dostęp przez inne programy

Spsób #1

  1. Instalujesz SSMS
  2. Instalujesz dodatek do SSMS np: SQL Search2
  3. Użuwasz dodatku do znalezienia szukanej wartości

Sposób #2

  1. ŚciągaszQuery Express
  2. Uzywasz go do pusczenia skryptu:
DECLARE @SearchStr NVARCHAR(60) 
DECLARE @sql NVARCHAR(MAX) 
DECLARE @tmpTblname sysname 
DECLARE @ParmDefinition nvarchar(500)
DECLARE @c bigint
DECLARE @SQLTbl TABLE ( 
     Tablename     NVARCHAR(500)
    ,WHEREClause    NVARCHAR(MAX) 
    ,SQLStatement   NVARCHAR(MAX) 
	,Execstatus bit
    ,c        bigint
) 

--SZUKANY CIĄG ZNAKÓW
SET	@SearchStr ='%SZUKANY CIĄG ZNAKÓW%'

SET @ParmDefinition = N'@cOUT bigint OUTPUT'

INSERT INTO @SQLTbl (tablename, WHEREClause,c)
SELECT 
	SCh.name + '.' + ST.NAME 
    ,( 
        SELECT '[' + SC.name + ']' + ' LIKE ''' + @SearchStr + ''' OR ' + CHAR(10) 
            FROM SYS.columns SC 
            JOIN SYS.types STy 
            ON STy.system_type_id = SC.system_type_id 
            AND STy.user_type_id =SC.user_type_id 
            WHERE STY.name in ('varchar','char','nvarchar','nchar') 
            AND SC.object_id = ST.object_id 
            ORDER BY SC.name 
        FOR XML PATH('') 
    )
	,0
FROM  
	SYS.tables ST 
	JOIN SYS.schemas SCh ON ST.schema_id = SCh.schema_id 
GROUP BY 
	ST.object_id
	, SCh.name + '.' + ST.NAME  

delete 
from 
	@SQLTbl 
where 
	whereClause is null

UPDATE
	@SQLTbl
set
	SQLStatement = N'select @cOUT = count(*) from ' + Tablename + N' where ' + substring(WHEREClause,1,len(WHEREClause)-5)  
	
WHILE EXISTS (SELECT 1 FROM @SQLTbl WHERE ISNULL(Execstatus ,0) = 0) 
BEGIN 
	SELECT TOP 1 
		@tmpTblname = Tablename 
		,@sql = SQLStatement 
	FROM 
		@SQLTbl  
	WHERE 
		ISNULL(Execstatus ,0) = 0 

 
	EXECUTE sp_executesql @sql, @ParmDefinition, @cOUT=@c OUTPUT;  

          
	UPDATE 
		@SQLTbl 
	SET 
		Execstatus = 1 
		,c=@c
	WHERE 
		Tablename = @tmpTblname 
END 

select 
	Tablename as [Tabela]
	,c as [Ilosc Rekordów]
	,'select * from ' + Tablename + ' WHERE ' + substring(WHEREClause,1,len(WHEREClause)-5)  AS [ZAPYTANIE DO SPRAWDZENIA DANYCH]
 from 
	@SQLTbl
WHERE
	C>0

@lampasss przedstawił też dobry skrypt, ale musisz mieć uprawnienia aby tworzyć obiekty na bazie...

0

Witam,

zainstalowałem SSMS i wtyczkę SQL Search, w bazie testowej, wprowadziłem dane dla jednego z produktów, "nietypowy wymiar", następnie chciałem wyszukać go, ale nic nie znajduję, co mogę robić źle ? screenshot-20170531090444.png

0

jeżeli używasz znaków % to odhacz Exact match

0

Odznaczyłem, to i tak nic nie zmienia, nie wiem czemu nie znajduje tych danych, skoro zapisane są w bazie.

0

Może jest tak, że format czy wizualizacja w programie nie odzwierciedla tego jak to jest zapisane....

0

Mam pytanie nowicjusza SQLowego: (baza MS SQL Server)

Potrzebuję pobrać nazwy wszystkich tabel z bazy i do tego wykorzystuje zapytanie 1:

SELECT
 TABLE_NAME
FROM
 INFORMATION_SCHEMA.TABLES

potem na podstawie tych wyników iteruje przez wszystkie tabele i przeszukuje wszystkie kolumny i wypisuje nazwy tych które są konkretnego typu zapytanie 2:

SELECT
 COLUMN_NAME
FROM
 INFORMATION_SCHEMA.COLUMNS 
WHERE
 TABLE_NAME = 'nazwa_z_wynikow_poprzedniego_zapytania'
  AND 
 DATA_TYPE = 'okreslony_recznie_typ_danych_kolumny_np.datetime'

PYTANIE:
Jak pobrać nazwy tabel tylko z głównej struktury bazy danych, bo w obecnym kształcie zapytanie 1 pobiera mi również nazwę tabeli 'sysdiagrams' a nie chce jej w wynikach.
Próbowałem szukać jakiegoś znacznika który mówi czy to typ tabeli użytkownika czy systemowa bazy, ale znalazłem tylko
'TABLE_TYPE'
które przyjmuje wartości
'VIEW' i
'BASE TABLE'
ale żaden z tych warunków nie daje efektu o który mi chodzi.

link do SQL / System information schema views :
https://learn.microsoft.com/en-us/sql/relational-databases/system-information-schema-views/tables-transact-sql?view=sql-server-ver16

Uprzedzając pytania ' po co mi to' - to wprawka, zadanie generalnie ćwiczenie - dla samego siebie.

PS. Temat powiązany z :
https://4programmers.net/Forum/C_i_.NET/364702-sqlexceptionnumber_18456_jak_odroznic_czy_to_zly_login_czy_zle_haslo_czy_winien_jest_sqlexceptionstate_1?p=1878025#id1878025

1 użytkowników online, w tym zalogowanych: 0, gości: 1