내려받은 json-for-dotnet-1.2.zip 파일의 압축을 풀어서 System.Net.Json.dll 파일을 SQL 서버에 복사합니다.
제가 만든 CLR에서 이 System.Net.Json.dll을 참조해야 하므로 다음과 같이 SQL 서버에 어셈블리 등록을 합니다.
EXEC SP_CONFIGURE 'clr enabled', 1
RECONFIGURE WITH OVERRIDE
ALTER DATABASE [MyDB] SET
TRUSTWORTHY ON
CREATE ASSEMBLY Json
FROM 'D:\System.Net.Json.dll'
WITH PERMISSION_SET = UNSAFE
그런데 JSON for. NET에서 제공해주는 기본 파서 기능이 좀 빈약하여, OpenAPI 결과를 처리할 수 있도록 기능 보완된 파서를 만들기 위하여 클래스 파일을 하나 더 추가합니다 (이름은 MyJsonParser.cs으로 했습니다).
그리고 다음과 같이 로직을 작성하였습니다.
MyJsonParser.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Json;
namespace NIMSAPI
{
class MyJsonParser
{
private JsonTextParser parser;
private JsonObjectCollection joc;
public MyJsonParser(string planText = "")
{
parser = new JsonTextParser();
if (!string.IsNullOrEmpty(planText))
{
joc = (JsonObjectCollection)parser.Parse(planText);
}
}
// 생성자에서 주어진 초기 문자열 외에 추가적으로 파싱할 때 사용
public void Parse(string planText)
{
planText = planText.Replace("\r", "").Replace("\n", "").Replace("\t", ""); // 파싱 오류방지를 위해 tab 및 개행문자열 제거
joc = (JsonObjectCollection)parser.Parse(planText);
}
public object GetValue(string namePath, char split = '/', bool returnEmptyWhenNull = true)
{
string[] names = namePath.Split(split);
JsonObjectCollection obj = null;
if (names.Length == 1)
{
if (joc[namePath] is JsonObjectCollection)
obj = (JsonObjectCollection)joc[namePath];
if (joc[namePath] is JsonArrayCollection)
obj = joc;
}
else
{
for (int i = 0; i < names.Length - 1; i++)
{
if (i == 0)
obj = (JsonObjectCollection)joc[names[i]];
else
obj = (JsonObjectCollection)obj[names[i]];
}
}
if (obj != null)
{
if (obj[names[names.Length - 1]] is JsonArrayCollection)
return obj[names[names.Length - 1]];
else
return obj[names[names.Length - 1]].GetValue();
}
else
{
object retObj = null;
if ((joc as JsonObjectCollection)[namePath] != null)
{
retObj = (joc as JsonObjectCollection)[namePath].GetValue();
}
if (retObj == null && returnEmptyWhenNull)
{
retObj = string.Empty;
}
return retObj;
}
}
}
}
참조 추가
솔루션 탐색기에서 참조 추가를 눌러서
앞에서 등록한 Json 어셈블리를 선택합니다.
정상적으로 추가되면 다음과 같이 참조 하위에 포함되게 됩니다.
이제 NIMS.cs에 OpenAPI를 호출하고 결과를 MyJsonParser로 파싱 처리하는 소스를 작성하였습니다.
NIMS.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Collections.Specialized;
using System.Net.Json;
namespace NIMSAPI
{
public class NIMS
{
// 상대 마약류취급자식별번호가 존재하는지 체크
// BizNo: 매출거래처의 사업자번호
public static bool IsExistsBsshCode(string BizNo)
{
string Url = "https://www.nims.or.kr/api/bsshinfo.do";
bool result = false;
try
{
WebClient webClient = new WebClient();
NameValueCollection formData = new NameValueCollection();
formData["k"] = "XXXXXXXXX"; //인증키
formData["fg"] = "1";
formData["pg"] = "1";
formData["bi"] = BizNo;
byte[] responseBytes = webClient.UploadValues(Url, "POST", formData);
string Result = Encoding.UTF8.GetString(responseBytes);
MyJsonParser myParser = new MyJsonParser(Result);
string ResultCode = myParser.GetValue("response/header/RESULT_CODE").ToString();
int CustCount = int.Parse(myParser.GetValue("response/body/TOTAL_COUNT").ToString());
JsonArrayCollection lists = (JsonArrayCollection)myParser.GetValue("response/body/list");
int count = 0;
foreach (JsonObjectCollection collection in lists)
{
myParser.Parse(collection.ToString()); // 배열 요소를 다시 파싱 시킨다
string OppNarcoticManagerID = myParser.GetValue("BSSH_CD").ToString(); // 상대 마약류취급자식별번호
result = !string.IsNullOrEmpty(OppNarcoticManagerID);
if (++count == 1) break; // 동일 거래처가 여러개 조회되는 경우가 있어서 한 번만 처리되게 함
}
}
catch
{
result = false;
}
return result;
}
}
}
CREATE ASSEMBLY NIMS
FROM 'D:\NIMSAPI.dll'
WITH PERMISSION_SET = UNSAFE
참고로 다음과 같이 소유자 SID 문제로 어셈블리 등록이 되지 않는 경우 ALTER AUTHORIZATION로 해당 DB의 소유자를 변경해야 합니다.
/*
master 데이터베이스에 기록된 데이터베이스 소유자 SID가 데이터베이스 'MyDB'에 기록된
데이터베이스 소유자 SID와 다릅니다.
ALTER AUTHORIZATION 문을 사용하여 데이터베이스 'MyDB'의 소유자를 다시 설정하여
이 문제를 해결해야 합니다.
*/
-- 현 소유자 확인
SELECT name AS [Database],
SUSER_SNAME(owner_sid) AS [Owner]
FROM sys.databases
WHERE [name] = 'MyDB'
-- 소유자 변경
ALTER AUTHORIZATION ON DATABASE:: MyDB TO sa ;
사용자 함수 생성
등록된 CLR 어셈블리를 SQL 서버에서 함수 형태로 호출할 수 있도록 함수를 생성합니다.
CREATE FUNCTION FN_NIMS_CUST_EXISTS
(
@p_BizNo NVARCHAR(20)
)
RETURNS BIT AS EXTERNAL NAME NIMS.[NIMSAPI.NIMS].IsExistsBsshCode
매번 컴퓨터 사용을 끝내고 윈도우를 종료했다가 다시 부팅하면 또다시 기본적인 프로그램을 실행시켜야 하고 그 전날 또는 마지막 작업한 환경을 불러오는 등의 번거로운 과정을 반복해야 합니다.
잠깐 동안 컴퓨터를 사용하지 않는 경우라면 절전모드를 이용할 수도 있지만, 장시간 또는 사무실과 같이 퇴근하고 다음날 다시 켜야 하는 경우에는 '최대 절전 모드'를 활용하면 불필요한 전력을 낭비하지도 않고 컴퓨터를 끄기 직전의 상태를 그대로 원복 시켜 주기 때문에 곧바로 마지막 작업한 이후의 업무를 신속하게 이어갈 수 있습니다.
방법은 간단합니다. 윈도우 시작 > 전원 버튼을 누르면 나오는 메뉴에서 최대 절전 모드를 선택하면 메모리를 dump 해서 하드디스크에 저장한 후 컴퓨터가 종료하게 됩니다.
그런데 만약 다음과 같이 최대 절전 모드 메뉴가 보이지 않는다면 이를 아래의 과정을 통해서 활성화시켜야 합니다.
우선 명령 프롬프트를 열고 다음과 같이 입력하여 최대 절전 모드 기능을 사용할 수 있도록 합니다.
powercfg /h on
다음으로 시작 메뉴 검색창에서 '전원'을 입력하여 '전원 및 절전 설정'을 선택하고 다시 '추가 전원 설정'을 선택합니다.
제어판의 전원 옵션 창이 뜨면 '전원 단추 작동 설정'을 선택합니다.
이어지는 화면에서 '현재 사용할 수 없는 설정 변경'을 선택합니다.
종료 설정 옵션 하위의 '최대 절전 모드'를 선택(체크)하고 저장 버튼을 누릅니다. 참고로 '전원 단추를 누를 때:'의 옵션으로 최대 절전 모드를 지정해 놓으면 컴퓨터 전원 버튼만으로 최대 절전 모드 사용이 가능합니다.