目前我正试图在c#中查询损坏的数据库。最近引入的错误是,当以特定方式输入数据时,列中的值默认为0,这对我来说是有问题的,因为我无法控制用户做什么或做什么dba。
为了解决这个问题,我找到了输出给用户的数据的另一条路径。问题是,如果列出现非零数字,我的主管要求支持旧方法。
我试图用case或if命令来做这个,但是我对sql不是那么好,所以我不是100%确定我哪里出错了或者如何正确/有效地去做。这些是当前状态下的命令:
SqlCommand caseCmd = new SqlCommand(
"SELECT H.CREATED, H.STATUSCODE, H.DETAILS, H.YEAR, H.MONTH, H.DAY, H.ITEMTEXT, TC.DOCLE, TC.ICPC, TC.ICD10, TERMCODE =" +
" CASE H.ITEMCODE WHEN 0" +
" THEN TN.TERMID" +
" ELSE H.ITEMCODE END" +
" FROM " + _databaseName + ".dbo.PASTHISTORY H" +
" INNER JOIN " + _drugDatabaseName + ".dbo.TERMNAMES TN ON TN.TERMNAME = H.ITEMTEXT" +
" INNER JOIN " + _drugDatabaseName + ".dbo.TERMCODES TC ON TC.TERMID = TERMCODE" +
" INNER JOIN " + _drugDatabaseName + ".dbo.CONDITIONS C ON C.TERMID = TERMCODE" +
" WHERE H.INTERNALID = @patientid" +
" AND H.RECORDSTATUS = 1" +
" AND ((H.CREATED >= @mindate) OR ((H.UPDATED IS NOT NULL) AND (H.UPDATED >= @mindate)))" +
" AND TC.RECORDSTATUS = 1",
Connection);
caseCmd.Parameters.AddWithValue("@patientid", int.Parse(patientId));
caseCmd.Parameters.AddWithValue("@mindate", minEnteredDate);
// Current error:
// When using 'TC.TERMID = TERMCODE', I get the error 'The conversion of the varchar value
// "3951000119103 " overflowed an int column'.
// This is alleviated by using either TN.TERMID OR H.ITEMCODE
SqlCommand ifCmd = new SqlCommand(
"IF (H.ITEMCODE = 0)" +
" SELECT H.CREATED, H.STATUSCODE, H.DETAILS, H.YEAR, H.MONTH, H.DAY, H.ITEMTEXT, TC.DOCLE, TC.ICPC, TC.ICD10, TN.TERMID" +
" FROM " + _databaseName + ".dbo.PASTHISTORY H" +
" INNER JOIN " + _drugDatabaseName + ".dbo.TERMNAMES TN ON TN.TERMNAME = H.ITEMTEXT" +
" INNER JOIN " + _drugDatabaseName + ".dbo.TERMCODES TC ON TC.TERMID = TN.TERMID" +
" INNER JOIN " + _drugDatabaseName + ".dbo.CONDITIONS C ON C.TERMID = TN.TERMID" +
" WHERE H.INTERNALID = @patientid" +
" AND H.RECORDSTATUS = 1" +
" AND ((H.CREATED >= @mindate) OR ((H.UPDATED IS NOT NULL) AND (H.UPDATED >= @mindate)))" +
" AND TC.RECORDSTATUS = 1" +
" ELSE IF (H.ITEMCODE <> 0)" +
" SELECT H.CREATED, H.STATUSCODE, H.DETAILS, H.YEAR, H.MONTH, H.DAY, H.ITEMTEXT, H.ITEMCODE, TC.DOCLE, TC.ICPC, TC.ICD10" +
" FROM " + _databaseName + ".dbo.PASTHISTORY H" +
" INNER JOIN " + _drugDatabaseName + ".dbo.TERMCODES TC ON TC.TERMID = H.ITEMCODE" +
" INNER JOIN " + _drugDatabaseName + ".dbo.CONDITIONS C ON C.TERMID = H.ITEMCODE" +
" WHERE H.INTERNALID = @patientid" +
" AND H.RECORDSTATUS = 1" +
" AND ((H.CREATED >= @mindate) OR ((H.UPDATED IS NOT NULL) AND (H.UPDATED >= @mindate)))" +
" AND TC.RECORDSTATUS = 1",
Connection);
ifCmd.Parameters.AddWithValue("@patientid", int.Parse(patientId));
ifCmd.Parameters.AddWithValue("@mindate", minEnteredDate);
// Current error:
// Getting two lines both saying 'The multi-part identifier "H.ITEMCODE" could not be bound.'
// I trust this is because of the IF and ELSE IF statements.
// Starting to think IF isn't the answer for me.
// Use either
SqlDataReader rdr = caseCmd.ExecuteReader();
// or
// SqlDataReader rdr = ifCmd.ExecuteReader();
这是否可以远程实现,或者我应该考虑为两种备选方案制作两个sql命令并搜索它们两者?
答案 0 :(得分:0)
为了清楚起见,我从C#字符串中取出了SQL并使用了CTE。基本上,您可以先修补数据,然后将其用于查找:
(-1)
这种情况看起来也很可疑:
WITH PatchedHistory AS (
SELECT
H.CREATED, H.STATUSCODE, H.DETAILS, H.YEAR, H.MONTH, H.DAY, H.ITEMTEXT
, COALESCE(TN.TERMID, H.ITEMCODE) AS ITEMCODE --< TERMID with ITEMCODE fall-back
FROM _databaseName.dbo.PASTHISTORY H
LEFT JOIN _drugDatabaseName.dbo.TERMNAMES TN
ON H.ITEMCODE = 0 --< Lookup only if ITEMCODE is 0
AND TN.TERMNAME = H.ITEMTEXT
WHERE H.INTERNALID = @patientid --< Apply most of the filtering here
AND H.RECORDSTATUS = 1
AND ((H.CREATED >= @mindate) --< Suspicious condition
OR ((H.UPDATED IS NOT NULL) AND (H.UPDATED >= @mindate))
)
)
SELECT H.CREATED, H.STATUSCODE, H.DETAILS, H.YEAR, H.MONTH, H.DAY, H.ITEMTEXT, H.ITEMCODE
, TC.DOCLE, TC.ICPC, TC.ICD10 --< Add the rest of the data
FROM PatchedHistory H
INNER JOIN _drugDatabaseName.dbo.TERMCODES TC
ON TC.TERMID = H.ITEMCODE --< Join on the "patched" ITEMCODE
INNER JOIN _drugDatabaseName.dbo.CONDITIONS C
ON C.TERMID = H.ITEMCODE --< Join on the "patched" ITEMCODE
WHERE TC.RECORDSTATUS = 1
技术上它等同于
AND ((H.CREATED >= @mindate)
OR ((H.UPDATED IS NOT NULL) AND (H.UPDATED >= @mindate))
)
看起来意图是
AND ((H.CREATED >= @mindate) OR (H.UPDATED >= @mindate))