【问题标题】:Azure Pipelines - CI/CD: How to execute all .sql files in a folder against DBAzure Pipelines - CI/CD:如何针对 DB 执行文件夹中的所有 .sql 文件
【发布时间】:2021-09-27 01:13:00
【问题描述】:

我已将所有 SQL 文件签入 Azure devops 上的存储库。 我有命名约定,可以让我知道其他 .sql 文件使用了哪些 .sql 文件(例如,文件创建了一个存储过程使用的视图)。 我想强制使用 repo 来跟踪代码更改,并且不希望使用 dacpac 文件。我希望每个函数/视图/存储过程都有自己的文件。

我的问题是,我将如何从 azure 管道中针对数据库执行与 '..\Functions\BASE_*.sql' 匹配的所有 .sql 文件?我尝试了以下方法,但不支持匹配多个文件。有没有更好的选择呢?我需要编写一个循环脚本并自己做吗?

# pipeline

trigger:
- master

pool:
  vmImage: 'windows-latest'

steps:
- task: SqlDacpacDeploymentOnMachineGroup@0
  inputs:
    TaskType: 'sqlQuery'
    SqlFile: '$(System.DefaultWorkingDirectory)\Functions\BASE_*.sql'
    ServerName: '$(SQL_ServerName).database.windows.net'
    DatabaseName: '$(SQL_DatabaseName)'
    AuthScheme: 'sqlServerAuthentication'
    SqlUsername: '$(SQL_UserName)'
    SqlPassword: '$(SQL_Password)'

我得到的错误是:

Starting: SqlDacpacDeploymentOnMachineGroup
==============================================================================
Task         : SQL Server database deploy
Description  : Deploy a SQL Server database using DACPAC or SQL scripts
Version      : 0.3.23
Author       : Microsoft Corporation
Help         : https://docs.microsoft.com/azure/devops/pipelines/tasks/deploy/sql-dacpac-deployment-on-machine-group
==============================================================================
##[error]Found more than one file to deploy with search pattern d:\a\1\s\Functions\BASE_*.sql. There can be only one.
Finishing: SqlDacpacDeploymentOnMachineGroup

【问题讨论】:

    标签: azure-devops azure-sql-database sql-function


    【解决方案1】:

    经过一天的研究和试验,我能想到的最好办法是在存储库中保持文件分开,然后在 CI/CD 管道中将多个文件组合在一起,然后再针对数据库运行它。

    我创建了一个模板来将匹配的文件组合到暂存目录中的单个文件中,发布它以调试管道,然后针对 SQL 服务器执行它。

    模板是:

    # Template for executing all SQL files matching a string search
    
    parameters:
    - name: path #$path = "$(System.DefaultWorkingDirectory)\Functions"
      type: string
    - name: match #$match = "BASE_*.sql"
      type: string
    - name: outPath #$outPath = "$(System.DefaultWorkingDirectory)\Functions"
      type: string
    - name: outName #$outName = "BASE.sql"
      type: string
    
    steps:
    - task: PowerShell@2
      inputs:
        targetType: 'inline'
        script: |
          echo Source Files:
          Get-ChildItem ${{parameters.path}} -include ${{parameters.match}} -rec 
      displayName: 'Files to process: ${{parameters.match}}'
    - task: PowerShell@2
      inputs:
        targetType: 'inline'
        script: |
          echo Creating: ${{parameters.outPath}}\${{parameters.outName}}
          Get-ChildItem ${{parameters.path}} -include ${{parameters.match}} -rec | ForEach-Object {gc $_; ""} | out-file ${{parameters.outPath}}\${{parameters.outName}}
      displayName: 'Combine: ${{parameters.outName}}'
    - task: PublishPipelineArtifact@1
      inputs:
       targetPath: '${{parameters.outPath}}\${{parameters.outName}}'
       artifact: '${{parameters.outName}}'
       publishLocation: 'pipeline'
      displayName: 'Publish: ${{parameters.outName}}'
    - task: SqlDacpacDeploymentOnMachineGroup@0
      inputs:
        TaskType: 'sqlQuery'
        SqlFile: '${{parameters.outPath}}\${{parameters.outName}}'
        ServerName: '$(SQL_ServerName).database.windows.net'
        DatabaseName: '$(SQL_DatabaseName)'
        AuthScheme: 'sqlServerAuthentication'
        SqlUsername: '$(SQL_UserName)'
        SqlPassword: '$(SQL_Password)'
      displayName: 'Create or Alter: ${{parameters.outName}}'
    - task: PowerShell@2
      inputs:
        targetType: 'inline'
        script: Remove-Item ${{parameters.path}}\${{parameters.match}} -Recurse
      displayName: 'Delete Files: ${{parameters.match}}'
    

    然后主管道使用不同的搜索字符串调用模板。

    trigger:
    - master
    
    pool:
      vmImage: 'windows-latest'
    
    steps:
    - task: PowerShell@2
      inputs:
        targetType: 'inline'
        script: MKDIR "$(System.DefaultWorkingDirectory)\\Combined\\Functions"
      displayName: 'Create Output Folder'
    - template: azTemplate/CombineAndRunSQLFiles.yml # Functions: UTIL
      parameters:
        path: "$(System.DefaultWorkingDirectory)\\Functions"
        match: "UTIL_*.sql"
        outPath: "$(System.DefaultWorkingDirectory)\\Combined\\Functions"
        outName: "UTIL.sql"
    - template: azTemplate/CombineAndRunSQLFiles.yml # Functions: BASE
      parameters:
        path: "$(System.DefaultWorkingDirectory)\\Functions"
        match: "BASE_*.sql"
        outPath: "$(System.DefaultWorkingDirectory)\\Combined\\Functions"
        outName: "BASE.sql"
    

    结果:

    Pool: Azure Pipelines
    Image: windows-latest
    Agent: Hosted Agent
    Started: Today at 9:55 AM
    Duration: 1m 6s
    
    Job preparation parameters
    5 artifacts produced
    Job live console data:
    Finishing: Job
    

    【讨论】:

    【解决方案2】:

    我将如何执行所有匹配的 .sql 文件 '..\Functions\BASE_*.sql' 针对来自 azure 管道的数据库?一世 尝试了以下,但不支持匹配多个文件。是 有更好的选择吗?我是否需要编写一个循环并执行它 我自己?

    如果要执行多个sql文件,需要有几个对应的WinRM SQL Server DB Deploymenttasks/steps。此任务设计为一次部署一个.dacpac.sql 文件,不支持部署多个脚本。

    根据我希望每个函数/视图/存储过程都有自己的文件。因此,如果您有三个用于function/view/stored procedure 的脚本,那么您的管道中至少需要三个SqlDacpacDeploymentOnMachineGroup@0 步骤。在此处检查类似问题(#1,#2)。没有更好的选择,您必须针对不同的脚本多次运行此任务。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-08
      • 2017-04-04
      • 2021-12-19
      • 2020-07-13
      相关资源
      最近更新 更多