환자 부가정보 7종 — 118종 → 125종
PAT_실제생년월일(bzDataInterface.vb:226 — P_PatEtcInf.PatEtcBirDte, 8자리·연월일 조각이 0 이 아닐 때만, YYYYMMDD 원문 그대로), PAT_국적(:639 — M_DtlMst NATCOD), PAT_장애등급(:687 — P_pdsoInf PdsoFlg='E', PdsoGrd 두 번째 글자), PAT_건보세대주명(:732 — P_PISINF ⨝P_CoiInf, PisInsCod='1'), PAT_건보_급여_세대주명(:780 — 자격 (코드·순번) 직접 지정; _Refer 갈래는 미리보기 미설정이라 자기 내원만), PAT_협력업체(:837 — ComCoopHsp→M_DtlMst, 원문대로 DtlTblCod 없음), PAT_보호자연락처(:881 — PatEtcGrdnPhn IS NOT NULL). 새 PatientExtraStore 에 자기 SQL 을 모았다. 차트번호는 문맥이 Trim 하므로 CHAR 컬럼은 RPAD(:c,10) 복원 매칭 — ㉜ 가 실값으로 증명한다. P_pdsoInf 만 VARCHAR2 라 IN (:c, RPAD(:c,10)) 양쪽을 본다 (㉛ [조사]: 이 DB 는 패딩 행 0 — 운영 DB 가 다를 수 있어 유지). ORDER BY 없는 Rows(0)/RowNum 1 은 전부 정렬 명시로 고정(갱신일시· 시작일 최신) — 장애등급의 P_ComInf 조인은 행만 곱해서 EXISTS 로 대체. 해석기는 지연 + 태그별 캐시(이 태그 없는 서식이 대부분). - dotnet test 338/338 · --edit-smoke 실패 0 (이름 검사 125종) - --db-patient ①~㉜ 전건 통과 — ㉛ 7종 실행, ㉜ 국적 실값 검증 신설 - --db-render P062 md5 8d683835f5d81e7bb41c79071d6bf954 불변 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
adb3572e40
commit
4642439ffd
@@ -0,0 +1,130 @@
|
||||
using Oracle.ManagedDataAccess.Client;
|
||||
|
||||
namespace SheetMe.Data.Stores;
|
||||
|
||||
/// <summary>
|
||||
/// 환자 부가정보 태그들의 자기 SQL — 레거시 <c>bzDataInterface.vb</c> 의 함수 본문에서
|
||||
/// 기계적으로 옮겼다(실제생년월일 :226 · 국적 :639 · 장애등급 :687 · 건보세대주명 :732 ·
|
||||
/// 건보_급여_세대주명 :780 · 협력업체 :837 · 보호자연락처 :881).
|
||||
///
|
||||
/// <b>차트번호 매칭.</b> 레거시는 <c>PatChtNum</c>(CHAR 10) 원문 — 패딩 포함 — 을 바인드한다.
|
||||
/// 우리 문맥은 행을 저장할 때 Trim 하므로(PatientContextStore.Row), CHAR 컬럼은
|
||||
/// <c>RPAD(:c,10)</c> 으로 패딩을 되살려 비교한다(인덱스도 산다). P_pdsoInf 만 VARCHAR2 라
|
||||
/// 저장값의 패딩 여부를 확정할 수 없어 두 형태 모두 본다(IN).
|
||||
///
|
||||
/// <b>Rows(0) 결정 규칙.</b> 원문은 전부 ORDER BY 없는 첫 행이다. 여기서는
|
||||
/// 담당의 때 정한 규칙대로 정렬을 명시해 한 행으로 고정한다 — 각 메서드 주석에 근거를 남겼다.
|
||||
/// </summary>
|
||||
public sealed class PatientExtraStore
|
||||
{
|
||||
#region Member Fields
|
||||
private readonly string connectionString;
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
public PatientExtraStore(string connectionString)
|
||||
{
|
||||
this.connectionString = connectionString;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
/// <summary>
|
||||
/// 실제생년월일(P_PatEtcInf.PatEtcBirDte, YYYYMMDD 원문) — 없으면 빈 문자열.
|
||||
/// 원문은 SELECT * 의 Rows(0) 인데 이 표는 차트번호가 사실상 유일키(환자 부가정보 마스터)다.
|
||||
/// 만에 하나 다중이면 갱신일시 최신 행 — 마지막으로 저장한 값이 현재 값이라는 뜻이다.
|
||||
/// </summary>
|
||||
public string ActualBirthDate(string chtNum)
|
||||
=> Scalar(
|
||||
"SELECT PatEtcBirDte FROM (SELECT PatEtcBirDte FROM P_PatEtcInf"
|
||||
+ " WHERE PatEtcChtNum = RPAD(:c, 10) ORDER BY PatEtcUpdDtf DESC) WHERE ROWNUM = 1",
|
||||
("c", chtNum));
|
||||
|
||||
/// <summary>보호자연락처(P_PatEtcInf.PatEtcGrdnPhn) — 원문의 IS NOT NULL 조건 그대로</summary>
|
||||
public string GuardianPhone(string chtNum)
|
||||
=> Scalar(
|
||||
"SELECT PatEtcGrdnPhn FROM (SELECT PatEtcGrdnPhn FROM P_PatEtcInf"
|
||||
+ " WHERE PatEtcChtNum = RPAD(:c, 10) AND PatEtcGrdnPhn IS NOT NULL"
|
||||
+ " ORDER BY PatEtcUpdDtf DESC) WHERE ROWNUM = 1",
|
||||
("c", chtNum));
|
||||
|
||||
/// <summary>
|
||||
/// 국적 한글명 — P_PatInf.PatNatCod 를 M_DtlMst(NATCOD) 로 푼다.
|
||||
/// P_PatInf 는 차트번호당 1행, 조인 키(DtlTblCod+DtlCod)도 유일이라 정렬이 필요 없다.
|
||||
/// </summary>
|
||||
public string Nationality(string chtNum)
|
||||
=> Scalar(
|
||||
"SELECT DtlCodNam FROM P_PatInf"
|
||||
+ " INNER JOIN M_DtlMst ON DtlCod = PatNatCod AND DtlTblCod = 'NATCOD'"
|
||||
+ " WHERE PatChtNum = RPAD(:c, 10)",
|
||||
("c", chtNum));
|
||||
|
||||
/// <summary>
|
||||
/// 장애등급 — P_pdsoInf(PdsoFlg='E') 의 PdsoGrd. 호출부가 두 번째 글자를 뽑는다(레거시 그대로).
|
||||
///
|
||||
/// 원문(:701-710)은 P_ComInf 를 INNER JOIN 해 행을 내원 수만큼 곱해 놓고 RowNum 1 로
|
||||
/// 접는다 — 조인의 실효는 "내원이 있는 환자인가" 확인뿐이라 EXISTS 로 바꿨다(의미 동일).
|
||||
/// ORDER BY 없는 RowNum 1 은 등급 변경 이력이 있으면 임의 행이다 — 주석의 의도
|
||||
/// ("현재 작성일 기준 등급", 2017-10-25 푸르메 요청)에 맞게 시작일 최신 행으로 고정한다.
|
||||
/// </summary>
|
||||
public string DisabilityGrade(string chtNum)
|
||||
=> Scalar(
|
||||
"SELECT PdsoGrd FROM (SELECT PdsoGrd FROM P_pdsoInf"
|
||||
+ " WHERE PdsoChtNum IN (:c, RPAD(:c, 10)) AND PdsoFlg = 'E'"
|
||||
+ " AND EXISTS (SELECT 1 FROM P_ComInf WHERE ComChtNum = RPAD(:c, 10))"
|
||||
+ " ORDER BY PdsoStrDte DESC, PdsoSeq DESC) WHERE ROWNUM = 1",
|
||||
("c", chtNum));
|
||||
|
||||
/// <summary>
|
||||
/// 건보 세대주명 — P_PISINF(PisInsCod='1') 를 이 내원의 자격(P_CoiInf.CoiInsSeq)과 맞춘다.
|
||||
/// 자격 이력이 여러 건이면 원문은 임의 행 — 시작일 최신 행으로 고정한다.
|
||||
/// </summary>
|
||||
public string HouseholderName(string chtNum, decimal comNum)
|
||||
=> Scalar(
|
||||
"SELECT Pis1SedaejuNm FROM (SELECT Pis1SedaejuNm FROM P_PISINF"
|
||||
+ " INNER JOIN P_CoiInf ON CoiInsSeq = PisInsSeq AND CoiComNum = :m"
|
||||
+ " WHERE PisChtNum = RPAD(:c, 10) AND PisInsCod = '1'"
|
||||
+ " ORDER BY PisStrDte DESC) WHERE ROWNUM = 1",
|
||||
("m", comNum), ("c", chtNum));
|
||||
|
||||
/// <summary>
|
||||
/// 세대주명(건보·급여) — 문맥 자격의 (보험코드, 순번)으로 P_PISINF 를 직접 짚는다.
|
||||
/// 레거시(:780-)는 참조 내원이 있으면 그쪽 자격을 쓰지만 미리보기는 참조를 설정하지
|
||||
/// 않으므로(TestPatientSetting) 자기 내원 갈래만 옮겼다.
|
||||
/// </summary>
|
||||
public string HouseholderNameByInsurance(string chtNum, string insSeq, string insCod)
|
||||
=> Scalar(
|
||||
"SELECT Pis1SedaejuNm FROM (SELECT Pis1SedaejuNm FROM P_PISINF"
|
||||
+ " WHERE PisChtNum = RPAD(:c, 10) AND PisInsSeq = :s AND PisInsCod = :d"
|
||||
+ " ORDER BY PisStrDte DESC) WHERE ROWNUM = 1",
|
||||
("c", chtNum), ("s", insSeq), ("d", insCod));
|
||||
|
||||
/// <summary>
|
||||
/// 협력업체 한글명 — 내원행의 ComCoopHsp 를 M_DtlMst 로 푼다.
|
||||
/// 원문(:850-854)은 DtlTblCod 조건 없이 DtlCod 만으로 조인한다 — 같은 코드가 다른
|
||||
/// 코드표에도 있으면 다중행이다. 레거시 조인을 그대로 두되 테이블코드 순 첫 행으로 고정한다.
|
||||
/// </summary>
|
||||
public string Cooperator(decimal comNum)
|
||||
=> Scalar(
|
||||
"SELECT DtlCodNam FROM (SELECT DtlCodNam FROM P_ComInf"
|
||||
+ " INNER JOIN M_DtlMst ON ComCoopHsp = DtlCod"
|
||||
+ " WHERE ComNum = :m ORDER BY DtlTblCod) WHERE ROWNUM = 1",
|
||||
("m", comNum));
|
||||
|
||||
/// <summary>스칼라 1칸 — 0행이거나 NULL 이면 빈 문자열. 잔여 공백은 걷는다(문맥 행과 같은 규칙)</summary>
|
||||
private string Scalar(string sql, params (string Name, object Value)[] binds)
|
||||
{
|
||||
using var connection = new OracleConnection(connectionString);
|
||||
connection.Open();
|
||||
using var command = connection.CreateCommand();
|
||||
command.BindByName = true;
|
||||
command.CommandText = sql;
|
||||
foreach (var (name, value) in binds)
|
||||
{
|
||||
command.Parameters.Add(new OracleParameter(name, value));
|
||||
}
|
||||
var result = command.ExecuteScalar();
|
||||
return result is null or DBNull ? string.Empty : result.ToString()!.Trim();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
Reference in New Issue
Block a user