OCM_혈액형(bzDataInterface.vb:11783 — S_BlpInf.BlpAboTyp, 갱신일시 최신 고정), OCM_LMP(:11813 — O_PrgInf.PrgLmpDte, 같은 표를 읽는 임신주기의 갱신일시 최신순으로 고정), OCM_BST/BST_LAST(:12042/:12710 — 바이탈과 다른 표 E_EmdInf_BST, VitalStore 를 표 인자화), OCM_BMI(:12159 — 차트 전체 최신 체중/키², 반올림 2자리), OCM_표준체중_LAST(:12234 — (키/100)²×여21·남22), OCM_조정체중_LAST(:12284 — 표준+(실제-표준)×0.25, 키·체중이 같은 행), OCM_비만도(:12333 — 이것만 내원 기준, 체중/Round(표준,0)×100). BMI·표준·조정은 내원(EmrComNum)이 아니라 차트(EmrChtNum) 기준이다 — 주석 처리된 EmrComNum 이 그 흔적. 성별 불명이면 표준·조정은 레거시 그대로 "0" 이 찍히고, 비만도는 0 나눗셈이라 사유로 말한다. OCM_임신주기는 사용자별 레지스트리 설정(DB_REGISTRY, UidCod 컬럼에 UidNam 을 비교하는 수상한 조건 포함) 의존이라 보류 — 별도 조사 대상. - dotnet test 338/338 · --edit-smoke 실패 0 (이름 검사 164종) - --db-patient ①~㉞ 전건 통과 (S_BlpInf·O_PrgInf·E_EmdInf_BST 실행 확인) - --db-render P062 md5 8d683835f5d81e7bb41c79071d6bf954 불변 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
86 lines
3.8 KiB
C#
86 lines
3.8 KiB
C#
using Oracle.ManagedDataAccess.Client;
|
|
|
|
namespace SheetMe.Data.Stores;
|
|
|
|
/// <summary>
|
|
/// 바이탈(측정치) 조회 — 레거시 <c>OCM_키/몸무게/체온/혈압/맥박/호흡/SPO2(±_LAST)</c> 계열
|
|
/// (bzDataInterface.vb:11508-13046)의 공통 조회.
|
|
///
|
|
/// 전부 같은 틀이다:
|
|
/// <c>E_EmdInf_VITAL ⨝ E_EmrInf(EmrKey=EmdEmrKey, 삭제 제외)</c> 를 내원으로 거르고
|
|
/// 해당 컬럼이 비어 있지 않은 행을 측정일시 순으로 한 건 집는다 —
|
|
/// 무인자는 <b>첫 측정</b>(ASC), _LAST 는 <b>마지막 측정</b>(DESC).
|
|
///
|
|
/// SELECT 식·널 필터·정렬까지 태그마다 본문에서 확인한 대로 호출부(해석기)가 지정한다.
|
|
/// 식과 컬럼명은 전부 <b>코드 상수</b>에서만 온다 — 사용자 입력이 닿는 경로가 아니다.
|
|
/// </summary>
|
|
public sealed class VitalStore
|
|
{
|
|
#region Member Fields
|
|
private readonly string connectionString;
|
|
#endregion
|
|
|
|
#region Constructors
|
|
public VitalStore(string connectionString) => this.connectionString = connectionString;
|
|
#endregion
|
|
|
|
#region Methods
|
|
/// <summary>측정치 한 건 — 없으면 빈 문자열</summary>
|
|
/// <param name="selectExpr">SELECT 식(별칭 포함) — 예: "EmdWeight" / "EmdBps || '/' || EmdBpd AS BP"</param>
|
|
/// <param name="pick">결과에서 집을 컬럼(별칭)</param>
|
|
/// <param name="notNullColumns">비어 있으면 안 되는 컬럼들(레거시 필터 그대로)</param>
|
|
/// <param name="orderBy">정렬 절 — 예: "EmdDte ASC, EmdTime ASC"</param>
|
|
public string One(decimal comNum, string selectExpr, string pick,
|
|
string[] notNullColumns, string orderBy)
|
|
=> Fetch("E_EmdInf_VITAL", "EmrComNum = :k", comNum, selectExpr, pick, notNullColumns, orderBy);
|
|
|
|
/// <summary>
|
|
/// BST 는 표가 다르다(E_EmdInf_BST, bzDataInterface.vb:12042-12080·12710-12747) —
|
|
/// 같은 조인 틀에 표만 바뀐다.
|
|
/// </summary>
|
|
public string OneBst(decimal comNum, string orderBy)
|
|
=> Fetch("E_EmdInf_BST", "EmrComNum = :k", comNum, "EmdBst", "EmdBst",
|
|
new[] { "EmdBst" }, orderBy);
|
|
|
|
/// <summary>
|
|
/// BMI·표준체중·조정체중은 내원이 아니라 <b>차트 전체</b>에서 최신 측정을 집는다
|
|
/// (bzDataInterface.vb:12159-12333 — EmrChtNum 조건, 주석 처리된 EmrComNum 이 그 흔적).
|
|
/// </summary>
|
|
public string OneByChart(string chtNum, string selectExpr, string pick,
|
|
string[] notNullColumns, string orderBy)
|
|
=> Fetch("E_EmdInf_VITAL", "EmrChtNum = RPAD(:k, 10)", chtNum, selectExpr, pick,
|
|
notNullColumns, orderBy);
|
|
|
|
private string Fetch(string table, string where, object key, string selectExpr, string pick,
|
|
string[] notNullColumns, string orderBy)
|
|
{
|
|
var filters = string.Concat(notNullColumns.Select(c =>
|
|
$" AND ({c} IS NOT NULL AND {c} <> ' ') "));
|
|
var sql =
|
|
"SELECT * FROM ("
|
|
+ $" SELECT {selectExpr}"
|
|
+ $" FROM {table}"
|
|
+ " INNER JOIN E_EmrInf ON EmrKey = EmdEmrKey"
|
|
+ " AND (EmrSttFlg IS NULL OR EmrSttFlg <> 'D')"
|
|
+ $" WHERE {where}"
|
|
+ filters
|
|
+ $" ORDER BY {orderBy}"
|
|
+ " ) WHERE ROWNUM = 1";
|
|
|
|
using var connection = new OracleConnection(connectionString);
|
|
connection.Open();
|
|
using var command = connection.CreateCommand();
|
|
command.BindByName = true;
|
|
command.CommandText = sql;
|
|
command.Parameters.Add(new OracleParameter("k", key));
|
|
using var reader = command.ExecuteReader();
|
|
if (!reader.Read())
|
|
{
|
|
return string.Empty;
|
|
}
|
|
var at = reader.GetOrdinal(pick);
|
|
return reader.IsDBNull(at) ? string.Empty : reader.GetValue(at).ToString()!.Trim();
|
|
}
|
|
#endregion
|
|
}
|