我在做一个HIS系统,有个关于病人费用明细单的查询出了问题。
我在delphi6中的语句是:
With Dm_charge.Aquery_faremedicine do
Begin
close;sql.Clear ;
sql.Add('SELECT IPMAKEPRICE.RECIPECODE,IPMAKEPRICE.ITEMNAME,IPMAKEPRICE.DG_SP_DESC,DRUGBASE.DG_PACKUNIT,');
sql.Add('IPMAKEPRICE.ITEMPRICE,((IPMAKEPRICE.BASEUNITQUAN+IPMAKEPRICE.PACKUNITQUAN*IPMAKEPRICE.DG_FACTOR-ipmakeprice.cancelbasequan-ipmakeprice.cancelpackquan*ipmakeprice.dg_factor))/IPMAKEPRICE.DG_FACTOR AS QUAN,');
SQL.Add('(IPMAKEPRICE.ITEMMONEY-IPMAKEPRICE.CANCELMONEY)AS CHAMONEY,IPCHARGE.CHARGEDATE,HOSPEMPLOYEE.HO_EMPLOYNAME,IPMAKEPRICE.RECIPELIST');
SQL.Add('FROM IPMAKEPRICE INNER JOIN IPCHARGE ON(IPCHARGE.ID_PATIENT=IPMAKEPRICE.ID_PATIENT AND IPCHARGE.MACHINECODE=');
SQL.Add('IPMAKEPRICE.MACHINECODE AND IPCHARGE.RECIPECODE=IPMAKEPRICE.RECIPECODE)');
SQL.Add('JOIN DRUGBASE ON DRUGBASE.DG_CODE=IPMAKEPRICE.ITEMCODE INNER JOIN HOSPEMPLOYEE ON ');
SQL.Add('IPCHARGE.CHARGEOPERATOR=HOSPEMPLOYEE.HO_EMPLOYCODE');
SQL.Add('WHERE IPCHARGE.ABORTFLAG='+QUOTEDSTR('0')+' AND IPMAKEPRICE.ITEMTYPE='+QUOTEDSTR('1'));
SQL.ADD('AND IPMAKEPRICE.CANCELFLAG='+QUOTEDSTR('0'));
SQL.ADD('AND IPCHARGE.ID_PATIENT=:IDPATIENT1  AND IPCHARGE.MACHINECODE=:MACHINECODE1');     SQL.ADD('AND IPCHARGE.CHARGEDATE>=:DATE1 AND IPCHARGE.CHARGEDATE<=:DATE2');
SQL.Add('UNION ');
sql.Add('SELECT IPMAKEPRICE.RECIPECODE,IPMAKEPRICE.ITEMNAME,ipmakeprice.DG_SP_DESC,DRUGDICTIONARY2.DG_DOSEUNIT,');
sql.Add('IPMAKEPRICE.ITEMPRICE,(IPMAKEPRICE.BASEUNITQUAN*ipmakeprice.usemulti-ipmakeprice.cancelbasequan*ipmakeprice.usemulti)AS QUAN,');
SQL.Add('(IPMAKEPRICE.ITEMPRICE*IPMAKEPRICE.BASEUNITQUAN*IPMAKEPRICE.USEMULTI-IPMAKEPRICE.CANCELMONEY)AS CHAMONEY,IPCHARGE.CHARGEDATE,HOSPEMPLOYEE.HO_EMPLOYNAME,IPMAKEPRICE.RECIPELIST');
SQL.Add('FROM IPMAKEPRICE INNER JOIN IPCHARGE ON(IPCHARGE.ID_PATIENT=IPMAKEPRICE.ID_PATIENT AND IPCHARGE.MACHINECODE=');
SQL.Add('IPMAKEPRICE.MACHINECODE AND IPCHARGE.RECIPECODE=IPMAKEPRICE.RECIPECODE)');
SQL.Add('JOIN DRUGDICTIONARY2 ON DRUGDICTIONARY2.DG_dicCODE=IPMAKEPRICE.ITEMCODE INNER JOIN HOSPEMPLOYEE ON ');
SQL.Add('IPCHARGE.CHARGEOPERATOR=HOSPEMPLOYEE.HO_EMPLOYCODE');
SQL.Add('WHERE IPCHARGE.ABORTFLAG='+QUOTEDSTR('0')+' AND IPMAKEPRICE.ITEMTYPE='+QUOTEDSTR('2'));
SQL.ADD('AND IPMAKEPRICE.CANCELFLAG='+QUOTEDSTR('0'));
SQL.ADD('AND IPCHARGE.ID_PATIENT=:IDPATIENT2 AND IPCHARGE.MACHINECODE=:MACHINECODE2');      SQL.ADD('AND IPCHARGE.CHARGEDATE>=:DATE3 AND IPCHARGE.CHARGEDATE<=:DATE4');
parameters.ParamByName('IDPATIENT1').Value :=str_idpatient;
parameters.ParamByName('machinecode1').Value:=str_machinecode;
parameters.ParamByName('date1').Value:=datetostr(datetimepicker1.Date)+' 00:00:00';         parameters.ParamByName('date2').Value:=datetostr(datetimepicker2.Date)+' 00:00:00';         parameters.ParamByName('IDPATIENT2').Value :=str_idpatient;
parameters.ParamByName('machinecode2').Value:=str_machinecode;
parameters.ParamByName('date3').Value:=datetostr(datetimepicker1.Date)+' 00:00:00';         parameters.ParamByName('date4').Value:=datetostr(datetimepicker2.Date)+' 00:00:00';         open;
  end; 但是编译运行是出现了错误
//出错信息提示
Projiect P_charge.exe raised exception class EAccessViolation with message 'Access violation
at address 78010513 in module  'msvcrt.dll'.write of address 00D700D3'.Process stopped. Use Step or Run to continue.我在sql2000查询分析器里面测试了这段sql语句,是可以查询成功的。
Sql2000中的语句:
SELECT IPMAKEPRICE.RECIPECODE,IPMAKEPRICE.ITEMNAME,IPMAKEPRICE.DG_SP_DESC,DRUGBASE.DG_PACKUNIT, IPMAKEPRICE.ITEMPRICE,((IPMAKEPRICE.BASEUNITQUAN+IPMAKEPRICE.PACKUNITQUAN*IPMAKEPRICE.DG_FACTOR-ipmakeprice.cancelbasequan-ipmakeprice.cancelpackquan*ipmakeprice.dg_factor))/IPMAKEPRICE.DG_FACTOR AS QUAN,(IPMAKEPRICE.ITEMMONEY-IPMAKEPRICE.CANCELMONEY)AS CHAMONEY,IPCHARGE.CHARGEDATE,HOSPEMPLOYEE.HO_EMPLOYNAME,IPMAKEPRICE.RECIPELIST 
FROM IPMAKEPRICE INNER JOIN IPCHARGE ON(IPCHARGE.ID_PATIENT=IPMAKEPRICE.ID_PATIENT AND IPCHARGE.MACHINECODE=IPMAKEPRICE.MACHINECODE AND IPCHARGE.RECIPECODE=IPMAKEPRICE.RECIPECODE)     JOIN DRUGBASE ON DRUGBASE.DG_CODE=IPMAKEPRICE.ITEMCODE
INNER JOIN HOSPEMPLOYEE ON IPCHARGE.CHARGEOPERATOR=HOSPEMPLOYEE.HO_EMPLOYCODE
WHERE IPCHARGE.ABORTFLAG=0 AND IPMAKEPRICE.ITEMTYPE=1 AND IPMAKEPRICE.CANCELFLAG=0 AND IPCHARGE.ID_PATIENT='1200305000001'  AND IPCHARGE.MACHINECODE='13' AND IPCHARGE.CHARGEDATE>='2003-05-26 22:34:12' AND IPCHARGE.CHARGEDATE<='2003-06-26 22:34:12'
UNION 
SELECT IPMAKEPRICE.RECIPECODE,IPMAKEPRICE.ITEMNAME,ipmakeprice.DG_SP_DESC,DRUGDICTIONARY2.DG_DOSEUNIT,IPMAKEPRICE.ITEMPRICE,(IPMAKEPRICE.BASEUNITQUAN*ipmakeprice.usemulti-ipmakeprice.cancelbasequan*ipmakeprice.usemulti)AS QUAN,(IPMAKEPRICE.ITEMPRICE*IPMAKEPRICE.BASEUNITQUAN*IPMAKEPRICE.USEMULTI-IPMAKEPRICE.CANCELMONEY)AS CHAMONEY,IPCHARGE.CHARGEDATE,HOSPEMPLOYEE.HO_EMPLOYNAME,IPMAKEPRICE.RECIPELIST
FROM IPMAKEPRICE INNER JOIN IPCHARGE ON(IPCHARGE.ID_PATIENT=IPMAKEPRICE.ID_PATIENT AND IPCHARGE.MACHINECODE=IPMAKEPRICE.MACHINECODE AND IPCHARGE.RECIPECODE=IPMAKEPRICE.RECIPECODE)
JOIN DRUGDICTIONARY2 ON DRUGDICTIONARY2.DG_dicCODE=IPMAKEPRICE.ITEMCODE 
INNER JOIN HOSPEMPLOYEE ON IPCHARGE.CHARGEOPERATOR=HOSPEMPLOYEE.HO_EMPLOYCODE
WHERE IPCHARGE.ABORTFLAG='0' AND IPMAKEPRICE.ITEMTYPE='2'AND IPMAKEPRICE.CANCELFLAG='0' AND IPCHARGE.ID_PATIENT='1200305000001' AND IPCHARGE.MACHINECODE='13' AND IPCHARGE.CHARGEDATE>='2003-05-26 22:34:12' AND IPCHARGE.CHARGEDATE<='2003-06-26 22:34:12'所以不知道是sql2000的问题还是delphi6不支持UNION语句,到底问题出在了哪里?
非常感谢!

解决方案 »

  1.   

    支持Union
    打个断点看看什么地方出错
      

  2.   

    好长...
    可以肯定的就是不存在什么不支持union语句的事既然能在sql2000查询分析器里面查询出你想要的结果,建议你用存储过程你为那些日期参数附值的时候,一定要用datetostr()函数吗?那些字段是日期型还是字符型?是日期型的话那参数附值就错了
      

  3.   

    太长了,晕。。
    听 hnhb(不死鸟) 的用存储过程吧。
      

  4.   

    用存储过程,delphi里写SQL很麻烦,如果语句长(比如象你那样的),一出错会找得你吐血。
      

  5.   

    Delphi没有什么支持不支持Union语句的
    它只是把SQL传给数据库罢了
    你可以在执行SQL之前把它显示出来showmessage(sql.text),或另存为文本文件sql.savetofile('t.txt');
      

  6.   

    同意kingting ,你的SQL态长了,一不小心就把"'"什么的搞错,你先把它SHOW来再COPY到查询分析器去执行,就可以发出错误了。
      

  7.   

    建议编写存储过程,然后在DELPHI中调用其过程名即可。这样程序维护也简单明了。也不用担心什么UNION。
      

  8.   

    同样的问题,若你是用odbc连接数据库,正常,因为odbc在你一次连接失败后会把错误信息保存起来,不会像ado那会释放保存的信息,所以你尽少连错,或用代码在出显这样的错误后释放保存的信息。