<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>어니언블로그</title>
    <link>https://onnionblog.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Thu, 4 Jun 2026 21:12:39 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>어니언onnion</managingEditor>
    <item>
      <title>Azure Blob Storage에서 SSIS를 이용하여 자동으로 SQL Server에 데이터 적재</title>
      <link>https://onnionblog.tistory.com/2</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Azure Blob Storage에 있는 csv 파일을 SSIS, SQL Agent Job을 이용해서 SQL Server에 자동으로 쌓기&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;b&gt;[테스트 목적]&lt;/b&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;li&gt;매월 Azure 사용량을 Power BI 보고서로 만들 예정&lt;/li&gt;&lt;li&gt;BI의 데이터는 MSSQL에서 가져오는 방식&lt;/li&gt;&lt;li&gt;Azure 사용량은 Blob Storage에 자동으로 저장되며, 매일 쌓이는 데이터를 수동으로 INSERT 하기 번거롭기 때문에 자동으로 DB에 저장될 수 있도록 구성&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;&lt;b&gt;[테스트 구성도]&lt;/b&gt;&lt;/p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1441&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZySZL/btsAuJ4GCXH/kscnCb0dcsfDVbvTXCT7r1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZySZL/btsAuJ4GCXH/kscnCb0dcsfDVbvTXCT7r1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZySZL/btsAuJ4GCXH/kscnCb0dcsfDVbvTXCT7r1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZySZL%2FbtsAuJ4GCXH%2FkscnCb0dcsfDVbvTXCT7r1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1441&quot; height=&quot;600&quot; data-origin-width=&quot;1441&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[테스트 방법]&lt;/b&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt; 
 &lt;li&gt;모든 테스트는 Azure Virtual Machine에서 진행&lt;/li&gt; 
 &lt;li&gt;Azure Blob Storage에는 매일 1개의 csv 파일이 쌓이고 있음 
  &lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt; 
   &lt;li&gt;Blob Storage에 자동으로 저장되는 파일명은 &lt;b&gt;‘&lt;span data-token-index=&quot;1&quot;&gt;폴더명_&lt;/span&gt;&lt;span style=&quot;background-color: #fbf3db;&quot; data-token-index=&quot;2&quot;&gt;랜덤값&lt;/span&gt;&lt;span data-token-index=&quot;3&quot;&gt;.csv&lt;/span&gt;’&lt;/b&gt; 으로 저장됨&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Azure Blob Storage에 있는 데이터를 로컬로 가져오기 위해 SSIS 사용&lt;/li&gt; 
 &lt;li&gt;SSIS를 통해 가져온 csv 파일을 BULK INSERT문으로 미리 생성해둔 테이블에 적재&lt;/li&gt; 
 &lt;li&gt;SQL Server job을 사용하여 자동으로 데이터가 저장될 수 있도록 함&lt;/li&gt; 
&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;&lt;b&gt;[테스트 상세 내용]&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. Azure Blob Storage -&amp;gt; SSIS&amp;nbsp;&lt;/b&gt;&lt;/h4&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;Blob Storage 컨테이너에 csv 파일이 있고, 파일명은 &lt;b&gt;**_**_Billing_랜덤값.csv&lt;/b&gt; 로 되어있다.&lt;br&gt;자동으로 가져오기 위해서 랜덤값을 어떻게 가져와야하나 고민을 많이 했었는데 SSIS 에서 Azure Blob Download Task로 데이터를 가져올 수 있었다&lt;/p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1256&quot; data-origin-height=&quot;873&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/clrXKg/btsAw8P7ZCK/1vggpI2WpwXMswv4rNoE31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/clrXKg/btsAw8P7ZCK/1vggpI2WpwXMswv4rNoE31/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/clrXKg/btsAw8P7ZCK/1vggpI2WpwXMswv4rNoE31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FclrXKg%2FbtsAw8P7ZCK%2F1vggpI2WpwXMswv4rNoE31%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1256&quot; height=&quot;873&quot; data-origin-width=&quot;1256&quot; data-origin-height=&quot;873&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1122&quot; data-origin-height=&quot;705&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bm6x1J/btsAD4k9opK/BBeZ5s1y1ZFErq1K99seT0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bm6x1J/btsAD4k9opK/BBeZ5s1y1ZFErq1K99seT0/img.png&quot; data-alt=&quot;SSIS에서 Azure Blob Download Task로 Blob Storage에 관련된 정보 작성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bm6x1J/btsAD4k9opK/BBeZ5s1y1ZFErq1K99seT0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbm6x1J%2FbtsAD4k9opK%2FBBeZ5s1y1ZFErq1K99seT0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;680&quot; height=&quot;427&quot; data-origin-width=&quot;1122&quot; data-origin-height=&quot;705&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SSIS에서 Azure Blob Download Task로 Blob Storage에 관련된 정보 작성&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;SSIS에서 Azure 관련된 기능을 사용하려면 Azure 서비스 기능팩을 별도로 설치해야 한다. (아래 링크)&lt;br&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/sql/integration-services/azure-feature-pack-for-integration-services-ssis?view=sql-server-ver16&quot; target=&quot;_blank&quot;&gt;&lt;span&gt;https://learn.microsoft.com/en-us/sql/integration-services/azure-feature-pack-for-integration-services-ssis?view=sql-server-ver16&lt;/span&gt;&lt;/a&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;이렇게 설정하고 실행하면 로컬 폴더로 blob storage에 있는 파일들이 저장된다.&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. SSIS -&amp;gt; VM 폴더&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h4&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;현재 테스트는 7월만 진행했는데, 자동으로 매월 가져오는 것이 테스트의 목적이기 때문에&amp;nbsp;&lt;br&gt;위 사진의 BlobDirecotry명을 1~12월까지로 설정하고, 데이터를 가져올 날짜를 매월 5일로 설정하고자 변수 설정을 해줬다&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;b&gt;SSIS에서 변수 설정하기&lt;/b&gt;&lt;br&gt;&amp;nbsp;&lt;br&gt;1. 변수 생성&lt;/p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;438&quot; data-origin-height=&quot;272&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/InD11/btsAw4AbC0S/gG2hLwkyg5frLP8nKirTO0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/InD11/btsAw4AbC0S/gG2hLwkyg5frLP8nKirTO0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/InD11/btsAw4AbC0S/gG2hLwkyg5frLP8nKirTO0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FInD11%2FbtsAw4AbC0S%2FgG2hLwkyg5frLP8nKirTO0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;438&quot; height=&quot;272&quot; data-origin-width=&quot;438&quot; data-origin-height=&quot;272&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;662&quot; data-origin-height=&quot;148&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/K5kfR/btsAxYzUuVs/AuB8aK0jljpKADbnMJHYz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/K5kfR/btsAxYzUuVs/AuB8aK0jljpKADbnMJHYz1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/K5kfR/btsAxYzUuVs/AuB8aK0jljpKADbnMJHYz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FK5kfR%2FbtsAxYzUuVs%2FAuB8aK0jljpKADbnMJHYz1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;559&quot; height=&quot;125&quot; data-origin-width=&quot;662&quot; data-origin-height=&quot;148&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;2. SQL 실행 태스크에서 DB와 연결 후 SQLStatement에서 결과 얻을 쿼리 생성&lt;/p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;732&quot; data-origin-height=&quot;632&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k9i2M/btsAyKnSS7K/ZZeNtiKoUnr2GdaNZAUD31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k9i2M/btsAyKnSS7K/ZZeNtiKoUnr2GdaNZAUD31/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k9i2M/btsAyKnSS7K/ZZeNtiKoUnr2GdaNZAUD31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk9i2M%2FbtsAyKnSS7K%2FZZeNtiKoUnr2GdaNZAUD31%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;606&quot; height=&quot;523&quot; data-origin-width=&quot;732&quot; data-origin-height=&quot;632&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서는 '***/**_**Billing/20230701-20230731/' 이 값에서 날짜 변수 처리와 매달 5일에 가져오기 위해 쿼리 생성&lt;br&gt;SQLStatement에 아래 변수를 각각 입력해준다&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;i&gt;&lt;b&gt;스토리지 폴더명 날짜 변수&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;DECLARE 
@folderdate nvarchar(100),
@folderstart nvarchar(10),
@folderend nvarchar(10),
@foldername nvarchar(20) = '***/**_**_Billing/'
SET @folderstart = (SELECT CONVERT(VARCHAR(6) ,DATEADD(mm,-1,GETDATE()) ,112) + '01')
SET @folderend = (SELECT CONVERT(VARCHAR(6) ,DATEADD(mm,-1,GETDATE()) ,112) + '31')
SET @folderdate = (SELECT&amp;nbsp;&amp;nbsp;@foldername + @folderstart + '-' + @folderend + '/')

SELECT ?= @folderdate&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;&lt;i&gt;&lt;b&gt;실행할 날짜 변수 (매월 5일)&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;SELECT ? = CONVERT(VARCHAR(8) ,GETDATE() ,121) + '05' ,? = CONVERT(VARCHAR(8) ,GETDATE() ,121) + '05 23:59:59'&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;파라미터 매핑에서 파라미터 이름은 0,1로 해준다&lt;/p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;716&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vpGlb/btsAzVa9U4y/NwKKYPAeGEC8hnQ1INNWkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vpGlb/btsAzVa9U4y/NwKKYPAeGEC8hnQ1INNWkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vpGlb/btsAzVa9U4y/NwKKYPAeGEC8hnQ1INNWkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvpGlb%2FbtsAzVa9U4y%2FNwKKYPAeGEC8hnQ1INNWkK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;716&quot; height=&quot;600&quot; data-origin-width=&quot;716&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그다음 Azure Blob Download Task Editor로 가서 변수처리할 항목들을 보고&amp;nbsp;Expressions에서 생성했던 변수 넣어주면 됨&lt;/p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;725&quot; data-origin-height=&quot;628&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bAsx5V/btsAyUKzXwM/qABzicuYdSHaKuCLbvx9G0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bAsx5V/btsAyUKzXwM/qABzicuYdSHaKuCLbvx9G0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bAsx5V/btsAyUKzXwM/qABzicuYdSHaKuCLbvx9G0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbAsx5V%2FbtsAyUKzXwM%2FqABzicuYdSHaKuCLbvx9G0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;530&quot; height=&quot;459&quot; data-origin-width=&quot;725&quot; data-origin-height=&quot;628&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;225&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/daMP4H/btsAzcxsjrf/nM8y4ln4oe0115b6bbD9C0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/daMP4H/btsAzcxsjrf/nM8y4ln4oe0115b6bbD9C0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/daMP4H/btsAzcxsjrf/nM8y4ln4oe0115b6bbD9C0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdaMP4H%2FbtsAzcxsjrf%2FnM8y4ln4oe0115b6bbD9C0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;571&quot; height=&quot;176&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;225&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;변수 설정 완료 후 실행&lt;/p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;841&quot; data-origin-height=&quot;292&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2hTTx/btsAxGlY9nL/GTnZ1LJIC35JJANiHzEAh0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2hTTx/btsAxGlY9nL/GTnZ1LJIC35JJANiHzEAh0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2hTTx/btsAxGlY9nL/GTnZ1LJIC35JJANiHzEAh0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2hTTx%2FbtsAxGlY9nL%2FGTnZ1LJIC35JJANiHzEAh0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;709&quot; height=&quot;246&quot; data-origin-width=&quot;841&quot; data-origin-height=&quot;292&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;그럼 vm에서 지정한 폴더에 파일이 저장된다&lt;/p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;496&quot; data-origin-height=&quot;323&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KR12j/btsAyKaliiz/N81lQ1RZdCHuLied26XmSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KR12j/btsAyKaliiz/N81lQ1RZdCHuLied26XmSk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KR12j/btsAyKaliiz/N81lQ1RZdCHuLied26XmSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKR12j%2FbtsAyKaliiz%2FN81lQ1RZdCHuLied26XmSk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;399&quot; height=&quot;260&quot; data-origin-width=&quot;496&quot; data-origin-height=&quot;323&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. VM 폴더 -&amp;gt; DB 적재&lt;/b&gt;&lt;/h4&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;로컬 폴더에 저장된 데이터들을 DB에서 BULK INSERT로 가져올 때 xp_cmdshell을 사용했다&lt;/p&gt;&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;xp_cmdshell&lt;/b&gt;&lt;br&gt;→ MSSQL에서 운영체제 명령을 실행할 수 있도록 하는 함수 &lt;br&gt;&lt;b&gt;xp_cmdshell 사용이유&lt;/b&gt; &lt;br&gt;→ BULK INSERT로 csv 파일을 가져올경우 파일명을 지정해줘야함. &lt;br&gt;파일명을 매번 지정해서 실행할 수 없기 때문에 자동으로 가지고 오기 위해 사용 &lt;br&gt;&lt;b&gt;BULK INSERT&lt;/b&gt;&lt;br&gt;→ CSV파일을 이용해 대용량 데이터를 테이블에 INSERT 할 때 사용&lt;/blockquote&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;1) csv구조에 맞는 테이블 생성&lt;br&gt;2) xp_cmdshell 사용을 위해 아래와 같이 설정&amp;nbsp;(이때 가져오려는 폴더에 접근 권한이 설정되어 있어야 함)&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;EXEC sp_configure 'show advanced options', 1
GO

RECONFIGURE WITH OVERRIDE
GO

EXEC sp_configure 'xp_cmdshell', 1
GO

RECONFIGURE WITH OVERRIDE
GO


-----------------------------------------------------------------------------

EXEC sp_xp_cmdshell_proxy_account 'VM\je', '비밀번호'


GRANT EXECUTE ON xp_cmdshell TO [VM\je]

execute as login = 'VM\je'


exec xp_cmdshell 'whoami'&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;3) 파일명 가져오고 Bulkinsert로 테이블에 데이터 insert 될 수 있도록 프로시저 생성&amp;nbsp;&lt;br&gt;(참고)&amp;nbsp;&lt;a href=&quot;https://www.youtube.com/watch?v=L7IfpvaSz4A&quot; target=&quot;_self&quot;&gt;&lt;span&gt;Import Multiple CSV Files into SQL Server using stored procedure. - YouTube&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;CREATE OR ALTER PROC INSERTDATA 

AS
BEGIN

DECLARE @Query VARCHAR(1000), @Filepath VARCHAR(1000), @pattern varchar(1000)
SET @Filepath = 'C:\Users\je\Desktop\Report\blob\'
SET @pattern = '*.csv'

CREATE TABLE #X (name varchar(200))

SET @Query = 'master.dbo.xp_cmdshell&amp;nbsp;&amp;nbsp;&quot;dir '+@Filepath+@pattern+' /b&quot; '


EXEC (@Query)

INSERT X EXEC (@Query)


DELETE FROM X WHERE name IS NULL 

SELECT IDENTITY(INT, 1, 1) AS ID, NAME INTO Y FROM X

DROP TABLE X

DECLARE @max int, @COUNT INT, @filename varchar(200)
SET @max = (select max(ID) FROM Y)
SET @COUNT= 0


WHILE @COUNT &amp;lt; @max 
	BEGIN
		SET @COUNT = @COUNT + 1
		SET @filename = (select name from #Y where [ID] = @COUNT)
		SET @Query = 'BULK INSERT Billing_en FROM &quot;'+@Filepath+@filename+'&quot; WITH(FORMAT = ''CSV'', CODEPAGE=''65001'', FIELDTERMINATOR ='','',	ROWTERMINATOR = ''\n'',	FIELDQUOTE =''&quot;'',	KEEPNULLS,	FIRSTROW = 2)'
	EXEC (@Query)
	END

DROP TABLE y

END&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;- 원래 X, Y 테이블은 임시 테이블로 생성했으나, JOB 생성시 FAIL 되서 일반 테이블로 생성&lt;br&gt;&amp;nbsp;&lt;br&gt;4) 프로시저 실행하면 아래와 같이 테이블에 데이터가 저장됨&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;lt;프로시저 실행 전&amp;gt;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;885&quot; data-origin-height=&quot;231&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kwD9b/btsAwqcF5FL/BQNWoEdV326oKPJL9Xf9L1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kwD9b/btsAwqcF5FL/BQNWoEdV326oKPJL9Xf9L1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kwD9b/btsAwqcF5FL/BQNWoEdV326oKPJL9Xf9L1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkwD9b%2FbtsAwqcF5FL%2FBQNWoEdV326oKPJL9Xf9L1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;885&quot; height=&quot;231&quot; data-origin-width=&quot;885&quot; data-origin-height=&quot;231&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;프로시저 실행 후&amp;gt;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1134&quot; data-origin-height=&quot;355&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzrHcb/btsAxdRtfOb/SMRUxqcHXm08bMII1dPVB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzrHcb/btsAxdRtfOb/SMRUxqcHXm08bMII1dPVB1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzrHcb/btsAxdRtfOb/SMRUxqcHXm08bMII1dPVB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzrHcb%2FbtsAxdRtfOb%2FSMRUxqcHXm08bMII1dPVB1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1134&quot; height=&quot;355&quot; data-origin-width=&quot;1134&quot; data-origin-height=&quot;355&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터가 잘 들어왔는데 한글로 된 데이터가 깨져서 들어왔다..&lt;br&gt;&amp;nbsp;&lt;br&gt;프로시저 실행 쿼리에서 BULK INSERT 할 때 &lt;b&gt;CODEPAGE = 65001 &lt;/b&gt;추가했더니 한글 깨짐 현상이 사라졌다&lt;/p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2026&quot; data-origin-height=&quot;612&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9Xcyx/btsAvqRt1EI/nkAczgxBZvXylGFTcfpWCk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9Xcyx/btsAvqRt1EI/nkAczgxBZvXylGFTcfpWCk/img.png&quot; data-alt=&quot;한글 데이터가 잘 들어왔음&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9Xcyx/btsAvqRt1EI/nkAczgxBZvXylGFTcfpWCk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9Xcyx%2FbtsAvqRt1EI%2FnkAczgxBZvXylGFTcfpWCk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2026&quot; height=&quot;612&quot; data-origin-width=&quot;2026&quot; data-origin-height=&quot;612&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;한글 데이터가 잘 들어왔음&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4. SQL Server Agent Job 설정&lt;/b&gt;&lt;/h4&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;SSIS 에서 자동으로 실행할 JOB을 설정해준다&lt;/p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;691&quot; data-origin-height=&quot;658&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ck7MNi/btsAwrbAdX2/nXFF49154BGesp9fPHDnAK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ck7MNi/btsAwrbAdX2/nXFF49154BGesp9fPHDnAK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ck7MNi/btsAwrbAdX2/nXFF49154BGesp9fPHDnAK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fck7MNi%2FbtsAwrbAdX2%2FnXFF49154BGesp9fPHDnAK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;435&quot; height=&quot;414&quot; data-origin-width=&quot;691&quot; data-origin-height=&quot;658&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;로컬에서 자동으로 파일 가져올 수 있도록 위에서 생성했던 프로시저를 JOB에 입력해준다&lt;/p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;690&quot; data-origin-height=&quot;656&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccFrSR/btsAzdJWxYF/J0kTjBtXvFzyeJBII2lR4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccFrSR/btsAzdJWxYF/J0kTjBtXvFzyeJBII2lR4k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccFrSR/btsAzdJWxYF/J0kTjBtXvFzyeJBII2lR4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FccFrSR%2FbtsAzdJWxYF%2FJ0kTjBtXvFzyeJBII2lR4k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;690&quot; height=&quot;656&quot; data-origin-width=&quot;690&quot; data-origin-height=&quot;656&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;끝&lt;/p&gt;</description>
      <category>MSSQL/테스트</category>
      <category>Azure Blob Storage</category>
      <category>mssql</category>
      <category>ssis</category>
      <author>어니언onnion</author>
      <guid isPermaLink="true">https://onnionblog.tistory.com/2</guid>
      <comments>https://onnionblog.tistory.com/2#entry2comment</comments>
      <pubDate>Sun, 19 Nov 2023 21:48:52 +0900</pubDate>
    </item>
  </channel>
</rss>