2016-10-07 10 views
2

1つのデータベース(ConfigDb)が他のデータベース(DataDb)を参照する2つのデータベースがSQL Serverにあります。 ConfigDbの多くのストアドプロシージャとファンクションは、DataDbのテーブルとファンクション/ SPを使用します。それらは[DataDb].[dbo].[the_object]のように参照されます。SQL Serverのストアドプロシージャの変更を自動化する方法は?

ここでは、バージョンをテストするためにデータベースを複製する必要があります。つまり、バックアップから復元する場合は、ConfigDb_TestDataDb_Testです。明らかに、ConfigDb_Testは、DataDb_Testではなく、DataDbを参照しています。

どのようなヒントをSPよりSPを開いて手動で編集するよりもこれを処理するには?

EDIT refernceについては

、私は

+0

私はこの正確な理由で相互参照を避けるために最善を尽くしています。 "正しい"解決策があるかもしれませんが、構成可能な接続文字列でSSISパッケージにプロセスを再実行するか、CLRストアドプロシージャを使用するか、データベース名だけを残すことができるように新しいSQLインスタンスを取得します。動的SQLもオプションですが、それは核心的な解決策です。 –

+0

VS/c#にアクセスできますか?自動的にすべてのprocを開いたり変更したりするためのアプリを書くことができます(これまでにやったことがあります)。 – JiggsJedi

+0

@JiggsJediはい、私は、それから始める何かを持つことは素晴らしいことでしょう – eXavier

答えて

1

OK GitHubでユーティリティを入れて、それがVB(ないC#の)である - そして私は、.NETの男ではないので、私はよ確かにこれを行うためのよりよい方法があります。

私はあなたがステップアップしてコードの作業を観察することに注意しますが、私はこれをたくさん使っています。

サーバー名/資格情報を入力すると、データベースの一覧が表示されます(システムデータベースは除外されます)。実行するデータベースを選択し(チェックリスト)、検索/置換テキスト文字列を入力します。 startをクリックすると、各procがオープン/スキャンされ、対応する文字列に対してREPLACE()が実行されるので、FIND/REPLACEテキストボックスに何を入れるか注意してください!

ここ

それは行くが...、これに注意してください、そしてご自身の責任でご使用ください。

form2.vb

form2.vb

オブジェクト名(ボックスをチェック)

  • chkSSPI

    • cmbServer(コンボボックス)(順)
    • txtUser(テキストボックス)
    • txtPass(テキストボックス)
    • btnConnect(ボタン)
    • btnExit(ボタン)の後ろ

    コード:

    Imports System.Data.SqlClient 
    
    Public Class Form2 
        Public objConn As SqlConnection = New SqlConnection() 
    
        Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
         cmbServer.SelectedIndex = 0 
         chkSSPI.Checked = True 
        End Sub 
    
        Private Sub btnExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExit.Click 
         Application.Exit() 
        End Sub 
    
        Private Sub chkSSPI_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkSSPI.CheckedChanged 
         txtUser.Enabled = Not chkSSPI.Checked 
         txtPass.Enabled = Not chkSSPI.Checked 
         txtUser.Select() 
        End Sub 
    
        Private Sub btnConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConnect.Click 
         If chkSSPI.Checked = False Then 
          objConn.ConnectionString = String.Format("Data Source={0};Initial Catalog=master;User ID={1};Password={2};", cmbServer.Text, txtUser.Text, txtPass.Text) 
         Else 
          objConn.ConnectionString = String.Format("Data Source={0}; Initial Catalog=master; Integrated Security=SSPI", cmbServer.Text) 
         End If 
         Dim frm2 As Form = New frmDBList() 
         Try 
          objConn.Open() 
         Catch ex As Exception 
          MessageBox.Show(ex.Message) 
         End Try 
    
         Hide() 
         frm2.Show() 
        End Sub 
    
        Private Sub txtUser_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtUser.TextChanged 
    
        End Sub 
    End Class 
    

    frmDBList。(順番に)VB

    frmDBList.vb

    オブジェクト名:

    • clbDatabase(チェックリストボックス)
    • txtFind(テキストボックス)
    • txtReplace(テキストボックス)
    • lblDBName(ラベル)
    • lblProcNum(ラベル)[0]
    • lblProcCount(ラベル)[123]
    • lblProcName(ラベル)
    • btnCheckAll(ボタン)
    • btnUnCheckAll(ボタン)
    • btnStart(ボタン)
    • btnClose(ボタン)

    コードバック:

    Imports System.Data.SqlClient 
    Imports System.IO 
    
    Public Class frmDBList 
        Dim procText As String 
        Dim procList As New ArrayList 
        Dim errorLog As New ArrayList 
        Dim dbcount As Int16 
        Dim proccount As Int16 
        Dim replacecount As Int16 
        Dim procupdate As Boolean 
    
        Public Sub LogError(ByVal text As String, ByVal dbname As String, ByVal procname As String) 
         errorLog.Add("db=" + dbname + " proc=" + procname + " error=" + text) 
        End Sub 
    
        Public Sub SaveLog() 
         Dim datetime As String = Now.ToString() 
         datetime = Replace(datetime, "/", "") 
         datetime = Replace(datetime, ":", "") 
         Dim filename As String = "c:\procchanger_errorlog " + datetime + ".txt" 
         Dim objWriter As New System.IO.StreamWriter(filename) 
         For c As Int16 = 0 To errorLog.Count - 1 
          objWriter.WriteLine(errorLog(c).ToString()) 
         Next 
         objWriter.Close() 
        End Sub 
    
        Public Sub AddListBoxItem(ByVal Item As Object, ByVal Check As Boolean) 
         clbDatabase.Items.Add(Item, Check) 
        End Sub 
    
        Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click 
         btnStart.Enabled = False 
         btnClose.Enabled = False 
         errorLog.Clear() 
         dbcount = 0 
         proccount = 0 
         replacecount = 0 
         grpProgress.Visible = True 
         If clbDatabase.SelectedItems.Count = 0 Then 
          MsgBox("Please select at least one database to process.", vbOKOnly) 
         Else 
          For i As Integer = 0 To clbDatabase.Items.Count - 1 
           If clbDatabase.GetItemChecked(i) = True Then 
            lblDBName.Text = clbDatabase.Items(i).ToString() 
            dbcount += 1 
            procList.Clear() 
            GetProcList(clbDatabase.Items(i).ToString()) 
           End If 
          Next 
          MsgBox("Complete. Replaced " + replacecount.ToString() + " occurrences, in " + proccount.ToString() + " stored procedures, across " + dbcount.ToString() + " databases.") 
          If errorLog.Count > 0 Then 
           SaveLog() 
          End If 
    
          grpProgress.Visible = False 
          For i As Integer = 0 To clbDatabase.Items.Count - 1 
           clbDatabase.SetItemChecked(i, CheckState.Unchecked) 
          Next 
         End If 
         If Form2.objConn.State = ConnectionState.Open Then Form2.objConn.Close() 
         btnStart.Enabled = True 
         btnClose.Enabled = True 
        End Sub 
    
        Public Sub GetProcList(ByVal dbname As String) 
         If Form2.objConn.State = ConnectionState.Closed Then 
          If Form2.chkSSPI.Checked = False Then 
           Form2.objConn.ConnectionString = String.Format("Data Source={0};Initial Catalog=" + dbname + ";User ID={1};Password={2};", Form2.cmbServer.Text, Form2.txtUser.Text, Form2.txtPass.Text) 
          Else 
           Form2.objConn.ConnectionString = String.Format("Data Source={0}; Initial Catalog=" + dbname + "; Integrated Security=SSPI", Form2.cmbServer.Text) 
          End If 
          Try 
           Form2.objConn.Open() 
          Catch ex As Exception 
           LogError(ex.Message, dbname, "") 
          End Try 
         End If 
    
         Try 
          Dim sqlcmd = "select name from sysobjects where xtype='P' and name not like 'dt_%'" 
    
          Using cmd As New SqlCommand(sqlcmd, Form2.objConn) 
           Using reader = cmd.ExecuteReader() 
            If reader.HasRows Then 
             While reader.Read() 
              procList.Add(reader("name").ToString()) 
             End While 
            End If 
           End Using 
          End Using 
         Catch ex As Exception 
          LogError(ex.Message, dbname, "") 
         End Try 
         lblProcCount.Text = procList.Count 
         proccount = procList.Count 
         For c = 0 To procList.Count - 1 
          lblProcNum.Text = c.ToString() 
          lblProcName.Text = procList(c).ToString() 
          Refresh() 
          procupdate = False 
          AlterProc(dbname, procList(c).ToString()) 
         Next 
         If Form2.objConn.State = ConnectionState.Open Then Form2.objConn.Close() 
        End Sub 
    
        Public Sub AlterProc(ByVal dbname As String, ByVal procname As String) 
         If Form2.objConn.State = ConnectionState.Closed Then 
          If Form2.chkSSPI.Checked = False Then 
           Form2.objConn.ConnectionString = String.Format("Data Source={0};Initial Catalog=" + dbname + ";User ID={1};Password={2};", Form2.cmbServer.Text, Form2.txtUser.Text, Form2.txtPass.Text) 
          Else 
           Form2.objConn.ConnectionString = String.Format("Data Source={0}; Initial Catalog=" + dbname + "; Integrated Security=SSPI", Form2.cmbServer.Text) 
          End If 
          Try 
           Form2.objConn.Open() 
          Catch ex As Exception 
           LogError(ex.Message, dbname, "") 
          End Try 
         End If 
         Try 
          Dim sqlcmd = "select * from " + dbname + ".dbo.sysobjects o inner join " + dbname + ".dbo.syscomments c on o.id = c.id where name='" + procname + "'" 
    
          Using cmd As New SqlCommand(sqlcmd, Form2.objConn) 
           procText = "" 
           Using reader = cmd.ExecuteReader() 
            If reader.HasRows Then 
             While reader.Read() 
              procText = procText + reader("text") 
             End While 
            End If 
           End Using 
    
           Dim arrProcData() = Split(procText, vbNewLine) 
    
           Dim c As Integer 
           procText = "" 
           For c = 0 To UBound(arrProcData) 
            If InStr(UCase(arrProcData(c)), "CREATE") > 0 And InStr(UCase(arrProcData(c)), "PROCEDURE") > 0 Then 
             arrProcData(c) = Replace(Replace(Replace(arrProcData(c), "CREATE", "ALTER"), "create", "alter"), "Create", "Alter") 
            End If 
            If InStr(UCase(arrProcData(c)), UCase(txtFind.Text)) > 0 Then 
             arrProcData(c) = Replace(UCase(arrProcData(c)), UCase(txtFind.Text), UCase(txtReplace.Text)) 
             replacecount += 1 
             procupdate = True 
            End If 
            procText = procText + arrProcData(c) + vbNewLine 
           Next 
    
          End Using 
         Catch ex As Exception 
          LogError(ex.Message, dbname, procname) 
         End Try 
    
         If procupdate = True Then 
          Try 
           Dim sqlcmd = procText 
           Using cmd As New SqlCommand(sqlcmd, Form2.objConn) 
            cmd.ExecuteNonQuery() 
           End Using 
          Catch ex As Exception 
           LogError(ex.Message, dbname, procname) 
          End Try 
         End If 
        End Sub 
    
        Private Sub frmDBList_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
         grpProgress.Visible = False 
         Try 
          Dim sqlcmd = "select name from master.dbo.sysdatabases where name not in ('msdb','master','temdb')" 
    
          Using cmd As New SqlCommand(sqlcmd, Form2.objConn) 
           Using reader = cmd.ExecuteReader() 
            If reader.HasRows Then 
             While reader.Read() 
              AddListBoxItem(reader("name").ToString(), CheckState.Unchecked) 
             End While 
            End If 
           End Using 
          End Using 
    
         Catch ex As Exception 
          LogError(ex.Message, "master", "") 
         End Try 
         Form2.objConn.Close() 
        End Sub 
    
        Private Sub btnClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClose.Click 
         Application.Exit() 
        End Sub 
    
        Private Sub btnCheckAll_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCheckAll.Click 
         For i As Integer = 0 To clbDatabase.Items.Count - 1 
          clbDatabase.SetItemChecked(i, CheckState.Checked) 
         Next 
        End Sub 
    
        Private Sub btnUnCheckAll_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnUnCheckAll.Click 
         For i As Integer = 0 To clbDatabase.Items.Count - 1 
          clbDatabase.SetItemChecked(i, CheckState.Unchecked) 
         Next 
        End Sub 
    
    End Class 
    
  • 関連する問題