개발/SQL SERVER

SQLCLR으로 Webapi 핸들링

whatever , whoever 2020. 5. 26. 21:16
반응형

C#으로 Webapi 데이터를 연동하고 나니

MSSQL에 주기적으로 데이터를 넣어야한다고 한다.

 

프로그램에서 Timer로 돌리는 방법도 있겠지만 그냥 데이터베이스에서 처리할 수 없을까 찾아보았다

 

그 결과물

https://github.com/geral2/SQL-APIConsumer

 

geral2/SQL-APIConsumer

Database Project with generic procedures to consume API through GET/POST methods. - geral2/SQL-APIConsumer

github.com

 

SQLCLR 이라는 형식으로 프로젝트를 생성하고 해당 파일을 MSSQL에 어셈블리로 등록하면

C# 코드를 프로시저 형태로 사용할 수 있다.

 

해당 소스를 그대로 가져다쓰면 제대로 되지 않는 경우가 많으니

Webapi 호출 방식별로 프로그램에서 테스트 해본 후 데이터베이스에 적용시키는 편이 좋다.

 

나의 경우 Post 방식이었으며 다음과 같이 작성했다.

 

public static string POSTMethod_Header(string url, string Headers = "")
{
string ContentResult = string.Empty;
try
{
// 기본 API 링크 주소
string apiURL = url;

// 가져올 항목 STRING
string header = Headers;
byte[] contentBytes = Encoding.UTF8.GetBytes(header);

// 가져오는 방식 정의
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(apiURL);
request.ContentType = "application/x-www-form-urlencoded;charset=utf-8";
request.Method = "POST";
request.KeepAlive = true;
request.ContentLength = contentBytes.Length;

// 인증서 오류 관련 처리 부분.
// 이 부분 없으면 진행되지 않음
ServicePointManager.ServerCertificateValidationCallback = delegate (
Object obj, X509Certificate certificate, X509Chain chain,
SslPolicyErrors errors)
{
return (true);
};

// 데이터 요청 구문
Stream st = request.GetRequestStream();
st.Write(contentBytes, 0, contentBytes.Length);
st.Close();

try
{
// 요청에 대한 데이터를 받는 구문
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string status = response.StatusCode.ToString();
if (status == "OK")
{
Stream stream = response.GetResponseStream();
string sResultJson = new StreamReader(stream).ReadToEnd();
ContentResult = sResultJson;
}
else
{
ContentResult = "Error :" + status;
}
st.Close();
response.Close();
}
catch (WebException ex)
{
ContentResult = ex.Message.ToString();
}
}
catch (Exception ex)
{
ContentResult = ex.Message.ToString();
throw ex;
}

return ContentResult;
}

 

이걸 어셈블리로 등록하는 과정 또한 험난한데

여기서 P1910은 데이터베이스 명이다.

 

use P1910

ALTER DATABASE P1910 SET COMPATIBILITY_LEVEL = 130
go

sp_configure 'clr enabled',1
RECONFIGURE

EXEC dbo.sp_changedbowner @loginame = N'sa', @map = false
ALTER DATABASE P1910 SET TRUSTWORTHY on
GO

CREATE ASSEMBLY [System.Runtime.Serialization]
AUTHORIZATION dbo
FROM N'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.Runtime.Serialization.dll'
WITH PERMISSION_SET = UNSAFE--external_access

CREATE ASSEMBLY [System.Net.Http]
AUTHORIZATION dbo
FROM N'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.Net.Http.dll'
WITH PERMISSION_SET = UNSAFE--external_access

CREATE ASSEMBLY [Newtonsoft.Json]
AUTHORIZATION dbo
FROM N'C:\CLR\Newtonsoft.Json.dll'
WITH PERMISSION_SET = UNSAFE

CREATE ASSEMBLY [APIConsumer]
AUTHORIZATION dbo
FROM N'C:\CLR\APIConsumer.dll'
WITH PERMISSION_SET = UNSAFE

go

CREATE PROCEDURE [dbo].[APICaller_POST_Headers]
@URL NVARCHAR (MAX) NULL, @Headers NVARCHAR (MAX) NULL
AS EXTERNAL NAME [APIConsumer].[StoredProcedures].APICaller_POST_Headers
GO

 

사용은 다음과 같이 하면 된다. 당연히 URL과 HEADER의 내용은 채워야겠죠

 

 EXEC [dbo].[APICaller_POST_Headers] 
         @URL   = URL
       , @Headers = HEADER

 

등록한 후의 어셈블리 내역

 

프로젝트 참조 말고 DLL 참조로 디버깅 하세요.

 

API_Consumer.zip
1.43MB

반응형