2015-01-22 1 views
1

SQL 서버에 프로 시저 목록이 있으며 모든 select * 문을 해당 테이블의 select (모든 열 이름)로 바꾸려고합니다. 그렇게하기 위해 proceudure 스크립트의 모든 select 문을 식별해야합니다. 여기에 현재 코드가 있습니다.C#의 storedprocedure 스크립트에서 모든 select 쿼리를 찾는 방법

foreach (StoredProcedure myproc in SelectedProcedures) 
       { 


        StringBuilder builder = new StringBuilder(); 
        ScriptingOptions scriptOptions = new ScriptingOptions(); 
        StringCollection tableScripts = myproc.Script(); 
        foreach (string script in tableScripts) 
        { 
         if (script.ToUpper().Contains("CREATE PROCEDURE")) 
         { 
          string x = script.ToUpper().Replace("CREATE PROCEDURE", "ALTER PROCEDURE"); 
          builder.Append(x + "\n"); 
          if (script.ToString().ToUpper().Replace(" ", " ").Contains("SELECT * FROM ")) 
          { 
           string u = script.ToString().ToUpper().Replace(" ", " "); 
           List<string> values = u.Split(new string[] { "SELECT * FROM " }, StringSplitOptions.RemoveEmptyEntries).ToList(); 
           List<string> tablenames = new List<string>(); 
           values.RemoveAt(0); 
           foreach (string t in values) 
           { 
            if (!t.Trim().StartsWith("#") && !t.Trim().StartsWith("@")) 
            { 
             tablenames.Add(t.Split(' ')[0].Replace("[", "").Replace("]", "").ToUpper().Trim()); 
            } 
           } 
           tablenames.OrderBy(xx => xx); 
           List<Table> tables = SourceDB.Tables.Cast<Table>().Where(t => tablenames.Contains(t.ToString().Replace("[", "").Replace("]", "").ToUpper())).Select(t => t).ToList(); 

           foreach (var t in tablenames) 
           { 
            try 
            { 
             Table mytable = SourceDB.Tables[t.Split('.')[1], t.Split('.')[0]]; 
             if (mytable != null) 
             { 
              StringBuilder builder1 = new StringBuilder(); 
              builder1.Append("SELECT "); 

              foreach (Column column in mytable.Columns) 
              { 
               builder1.Append("[" + column.Name.ToUpper() + "], "); 
              } 
              builder1.Remove(builder1.ToString().LastIndexOf(", "), 1); 
              builder1.Append(" from "); 
              builder1.Append(mytable.ToString()); 
              GeneratedScripts["Procedures"].Add(builder1); 
              string k = builder.ToString().ToUpper(); 
              string n = k.Replace(" ", " ").Replace("SELECT * FROM " + mytable.ToString().ToUpper(), builder1.ToString()); 
              n = n.Replace(" ", " ").Replace("SELECT * FROM " + t, builder1.ToString()); 
              builder = new StringBuilder(n); 

             } 
            } 
            catch (Exception) 
            { 

             continue; 
            } 



           } 

          } 
         } 



        } 

그러나 이것은 내부 내가이 일을 처리하기 위해, 정규식 등의 추가적인 논리를 사용할 수있는 테이블 B 가입 테이블에서 선택 B. * 같은 경우를 생략하지만 모든 검색 할 수 있도록 내가 더 적절한 방법을 원하는 문자열 목록에서 프로 시저 스크립트의 쿼리를 선택한 다음 모든 쿼리에 대해 내 사용자 지정 논리를 하나씩 사용할 수 있습니다.

감사

+0

이 작업을 제대로 수행하려면 완전한 SQL 구문 분석기를 작성해야합니다. 쉬운 일은 아닙니다. 이런 종류의 일을하는 상업용 제품을 보길 원할 것입니다. –

+0

기존 무료 Api가 있습니다. DacFx와 TSqlObject에서 저장 프로 시저의 명령문을 제공합니다. qsgt가 그의 대답에서 보여주는 ssdt가 사용하는 API입니다 (다른 사람에게 유용 할 것처럼 Oss로 작성하십시오). –

+0

실제로 ScriptDom은 TSqlObjects가 아니며 명령문을 가져 오는 방법을 보여 주지만 열과 테이블 등을 가져올 수도 있습니다. http://blogs.msdn.com/b/arvindsh/archive/2013/04/04/using-the -transactsql-scriptdom-parser-to-get-statement-counts.aspx –

답변

-1

나는 몇 가지 가정이 할 것 : A *가에서 select와 사이에 발생하는 정규식 일치

봐. SELECT 앞에 공백이나 탭이 포함될 수있는 'EXISTS (바로 가기)'가있는 경우에만 제외 할 수 있습니다.

다른 대안은 실행 계획 캐시를주의 깊게 살펴보고 또 다른 좋은 (또는 더 나은) 다른 방법은이 규칙을 포함 할 수 코드 분석을하고 시작하는 데 가장 많이 사용되는 쿼리.

입니다. 데이터베이스가 비주얼 스튜디오 후 기본적으로 포함되어 SSDT에 의해 개발되는 경우

1

그것은 쉽게 SSDT에서 프로젝트 노드를 마우스 오른쪽 버튼으로 클릭하고 리팩터링 -> 와일드 카드 확장을 선택합니다 .SSDT는 내부적으로 데이터베이스 스키마 모델을 작성하므로 매우 이상합니다. 정확한 열을 계산할 수 있습니다.

다른 도구와 마찬가지로이 도구를 사용하면 EXISTS (SELECT * FROM 또는 SELECT COUNT(*)과 같은 검색어에주의해야합니다. 그들을 대체하는 것은별로 의미가 없습니다. enter image description here

관련 문제