[SQL] 는 SQL 쿼리에 사용되는 테이블 목록
SQL는 SQL 쿼리에 사용되는 테이블 목록
SQL 쿼리에서 사용되는 테이블의 목록을 얻을 수있는 방법을 방법이 있나요? 예 : 내가 좋아하는 뭔가를 :
SELECT * FROM Table t JOIN OtherTable ON t.id=OtherTable.t_id
내가 얻을 기대
Table, OtherTable
감사
해결법
-
==============================
1.당신은 당신의 쿼리 후이 SQL 스크립트 권한을 사용할 수 있습니다. 그것은 마지막으로 실행 된 쿼리에 사용되는 테이블의 목록을 반환합니다 :
당신은 당신의 쿼리 후이 SQL 스크립트 권한을 사용할 수 있습니다. 그것은 마지막으로 실행 된 쿼리에 사용되는 테이블의 목록을 반환합니다 :
SELECT Field1, Field2 FROM Table t JOIN OtherTable ON t.id=OtherTable.t_id ;WITH vwQueryStats AS( SELECT COALESCE(OBJECT_NAME(s2.objectid),'Ad-Hoc') AS ProcName ,execution_count ,s2.objectid ,( SELECT TOP 1 SUBSTRING(s2.TEXT,statement_start_offset / 2+1 ,( ( CASE WHEN statement_end_offset = -1 THEN (LEN(CONVERT(NVARCHAR(MAX),s2.TEXT)) * 2) ELSE statement_end_offset END)- statement_start_offset) / 2+1)) AS sql_statement ,last_execution_time FROM sys.dm_exec_query_stats AS s1 CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS s2 ) SELECT TOP 1 * INTO #lastQueryStats FROM vwQueryStats x WHERE sql_statement NOT like 'WITH vwQueryStats AS%' ORDER BY last_execution_time DESC SELECT TABLE_NAME FROM #lastQueryStats, INFORMATION_SCHEMA.TABLES tab WHERE CHARINDEX( tab.TABLE_NAME, sql_statement) > 0 DROP TABLE #lastQueryStats
이 게시물에서 마지막으로 실행 된 쿼리를 검색하는 쿼리를 촬영했습니다 그리고 난 당신의 예제와 일치하도록 조금 수정했습니다.
당신이 요청에 따라 출력 될 것입니다 :
Table OtherTable
당신이 할 경우 그 쉼표는 당신이 할 수있는 분리 :
DECLARE @tableNames VARCHAR(MAX) SELECT @tableNames = COALESCE(@tableNames + ', ', '') + TABLE_NAME FROM #lastQueryStats, INFORMATION_SCHEMA.TABLES tab WHERE CHARINDEX( tab.TABLE_NAME, sql_statement) > 0 SELECT @tableNames
쿼리의 수천을 가진 '보통'생산 QA 환경에서 동시에 다른 쿼리로하지 작업이 첫 번째 쿼리와 쿼리 사이에서 실행될 수있는이 힘을 실행 한 그러나 당신이 조심해야 dB 통계에서 추출 정보를 그.
희망이 도움이
-
==============================
2.다음 : C #을 사용 하나 개의 솔루션은 수입 Microsoft.SqlServer.TransactSql.ScriptDom이다 (\ Program 파일 (x 86) \ Microsoft SQL Server를 \ 120 \ SDK \ 어셈블리 \ Microsoft.SqlServer.TransactSql.ScriptDom.dll 나는 C에서 DLL을 찾을 수 없음) 다음을 수행 :
다음 : C #을 사용 하나 개의 솔루션은 수입 Microsoft.SqlServer.TransactSql.ScriptDom이다 (\ Program 파일 (x 86) \ Microsoft SQL Server를 \ 120 \ SDK \ 어셈블리 \ Microsoft.SqlServer.TransactSql.ScriptDom.dll 나는 C에서 DLL을 찾을 수 없음) 다음을 수행 :
private List<string> GetTableNamesFromQueryString(string query) { IList<ParseError> errors = new List<ParseError>(); IList<TSqlParserToken> queryTokens; List<string> output = new List<string>(16); StringBuilder sb = new StringBuilder(128); TSql120Parser parser = new TSql120Parser(true); TSqlTokenType[] fromTokenTypes = new TSqlTokenType[2] { TSqlTokenType.From, TSqlTokenType.Join }; TSqlTokenType[] identifierTokenTypes = new TSqlTokenType[2] { TSqlTokenType.Identifier, TSqlTokenType.QuotedIdentifier }; using (System.IO.TextReader tReader = new System.IO.StringReader(query)) { queryTokens = parser.GetTokenStream(tReader, out errors); if (errors.Count > 0) { return errors.Select(e=>"Error: " + e.Number + " Line: " + e.Line + " Column: " + e.Column + " Offset: " + e.Offset + " Message: " + e.Message).ToList(); } for (int i = 0; i < queryTokens.Count; i++) { if(fromTokenTypes.Contains(queryTokens[i].TokenType)) { for (int j = i + 1; j < queryTokens.Count; j++) { if (queryTokens[j].TokenType == TSqlTokenType.WhiteSpace) { continue; } else if (identifierTokenTypes.Contains(queryTokens[j].TokenType)) { sb.Clear(); GetQuotedIdentifier(queryTokens[j], sb); //Change Identifiers to QuotedIdentifier (text only) while (j + 2 < queryTokens.Count && queryTokens[j + 1].TokenType == TSqlTokenType.Dot && identifierTokenTypes.Contains(queryTokens[j + 2].TokenType)) { sb.Append(queryTokens[j + 1].Text); GetQuotedIdentifier(queryTokens[j + 2], sb); //Change Identifiers to QuotedIdentifier (text only) j += 2; } output.Add(sb.ToString()); break; //exit the loop } else { break; } //exit the loop if token is not a FROM, a JOIN, or white space. } } } return output.Distinct().OrderBy(tableName => tableName).ToList(); } } private void GetQuotedIdentifier(TSqlParserToken token, StringBuilder sb) { switch(token.TokenType) { case TSqlTokenType.Identifier: sb.Append('[').Append(token.Text).Append(']'); return; case TSqlTokenType.QuotedIdentifier: sb.Append(token.Text); return; default: throw new ArgumentException("Error: expected TokenType of token should be TSqlTokenType.Identifier or TSqlTokenType.QuotedIdentifier"); } }
나는 일이 답변을 얻을려고 후에이 함께했다.
-
==============================
3.아래의 코드는 Trisped의 답변에 따라,하지만 스키마 이름을 생략 완전한 테이블 이름, 그리고 몇 가지 정리 / 최적화와 함께 작동하도록 수정 :
아래의 코드는 Trisped의 답변에 따라,하지만 스키마 이름을 생략 완전한 테이블 이름, 그리고 몇 가지 정리 / 최적화와 함께 작동하도록 수정 :
public class Parser { public static List<string> GetTableNamesFromQueryString(string query) { var output = new List<string>(); var sb = new StringBuilder(); var parser = new TSql120Parser(true); var fromTokenTypes = new[] { TSqlTokenType.From, TSqlTokenType.Join }; var identifierTokenTypes = new[] { TSqlTokenType.Identifier, TSqlTokenType.QuotedIdentifier }; using (System.IO.TextReader tReader = new System.IO.StringReader(query)) { IList<ParseError> errors; var queryTokens = parser.GetTokenStream(tReader, out errors); if (errors.Any()) { return errors .Select(e => string.Format("Error: {0}; Line: {1}; Column: {2}; Offset: {3}; Message: {4};", e.Number, e.Line, e.Column, e.Offset, e.Message)) .ToList(); } for (var i = 0; i < queryTokens.Count; i++) { if (fromTokenTypes.Contains(queryTokens[i].TokenType)) { for (var j = i + 1; j < queryTokens.Count; j++) { if (queryTokens[j].TokenType == TSqlTokenType.WhiteSpace) { continue; } if (identifierTokenTypes.Contains(queryTokens[j].TokenType)) { sb.Clear(); GetQuotedIdentifier(queryTokens[j], sb); while (j + 2 < queryTokens.Count && queryTokens[j + 1].TokenType == TSqlTokenType.Dot && (queryTokens[j + 2].TokenType == TSqlTokenType.Dot || identifierTokenTypes.Contains(queryTokens[j + 2].TokenType))) { sb.Append(queryTokens[j + 1].Text); if (queryTokens[j + 2].TokenType == TSqlTokenType.Dot) { if (queryTokens[j - 1].TokenType == TSqlTokenType.Dot) GetQuotedIdentifier(queryTokens[j + 1], sb); j++; } else { GetQuotedIdentifier(queryTokens[j + 2], sb); j += 2; } } output.Add(sb.ToString()); } break; } } } return output.Distinct().OrderBy(tableName => tableName).ToList(); } } private static void GetQuotedIdentifier(TSqlParserToken token, StringBuilder sb) { switch (token.TokenType) { case TSqlTokenType.Identifier: sb.Append('[').Append(token.Text).Append(']'); break; case TSqlTokenType.QuotedIdentifier: case TSqlTokenType.Dot: sb.Append(token.Text); break; default: throw new ArgumentException("Error: expected TokenType of token should be TSqlTokenType.Dot, TSqlTokenType.Identifier, or TSqlTokenType.QuotedIdentifier"); } } }
-
==============================
4.당신이 이것을 달성 할 수있는 하나의 hackish 방법은 명시 적으로 쿼리의 필드 이름과 테이블 이름, 예를 들어, 그들을 앞에하는 것
당신이 이것을 달성 할 수있는 하나의 hackish 방법은 명시 적으로 쿼리의 필드 이름과 테이블 이름, 예를 들어, 그들을 앞에하는 것
SELECT Field1 As "OtherTable.Field1", Field2 As "Table.Field2" FROM Table t JOIN OtherTable ON t.id=OtherTable.t_id
기본적으로, 당신은 쿼리 결과에 자신의 메타 데이터를 제공하고 있습니다. 쿼리가 반환 된 후, 열 이름을보고 테이블 이름을 분할하는 사용자 지정 논리를 구현합니다.
-
==============================
5.Trisped의 솔루션은 완벽하게 작동합니다. 나는 사례를 구분을 보장하고 괄호를 트리밍 한 줄을 수정했습니다.
Trisped의 솔루션은 완벽하게 작동합니다. 나는 사례를 구분을 보장하고 괄호를 트리밍 한 줄을 수정했습니다.
OLD : output.Add (sb.ToString ());
(.. sb.ToString () ToLower는 () 트림 (새 문자 [{ "[", "]})) : NEW output.Add;
from https://stackoverflow.com/questions/16692344/list-of-tables-used-in-an-sql-query by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] SQL 서버 : 날짜 범위를 계산 (0) | 2020.06.09 |
---|---|
[SQL] 이유는 "프로 시저 매개 변수 '@statement'유형의 'NTEXT / NCHAR / NVARCHAR'를 기대하고있다."받을 수 있나요 나는 sp_executesql을 사용하려고 할 때? (0) | 2020.06.09 |
[SQL] DB2의 쿼리에서 구분 된 문자열을 만들기 (0) | 2020.06.09 |
[SQL] 모두 일치하는 정규 표현식은 T-SQL 스크립트에 댓글 (0) | 2020.06.09 |
[SQL] MYSQL - IN과 존재의 차이 (0) | 2020.06.09 |