PHP中的Oracle SQL请求不返回任何内容,但在SQL Developer中有效



我遇到一个问题,我有一个请求在带有oracle DB插件的SQL DeveloperVsCode中工作,但在php代码中,它返回0行PHP版本很旧,对此我无能为力,5.4.6OracleDB是11g(11.2.0.3.0(。

以下是请求:

$sql =  "SELECT
PATIENT_SOIGNE.NOM,
PATIENT_SOIGNE.PATRONYME AS NOM_NAISSANCE,
PATIENT_SOIGNE.PRENOM,
to_date(PATIENT_SOIGNE.DATENAIS,'YYYYMMDD') AS DDN,
decode(PATIENT_SOIGNE.SEXE,'F','Femme','M','Homme','Inconnu') AS SEXE,
PATIENT_SOIGNE.NIP,
S_ACTE_MED.CODEP1 || ' - ' || ( S_ACTE_MED.LIBELLE ) AS ACTE,
OPERATEUR.NOM AS NOM_OPERATEUR,
OPERATEUR.PRENOM AS PRENOM_OPERATEUR
FROM
PENSOINS.ACTE_RDV,
PENSOINS.RDV_STATUT  RDV_STATUT,
PENSOINS.ACTE_RDV_GRP,
PENSOINS.S_ACTE_M  S_ACTE_MED,
PENSOINS.EJ_PERSO  OPERATEUR,
(
SELECT RESSOURCE_OPERATEUR.*,  ACTE_RDV_RESA.NIACTERDV
FROM
PENSOINS.DXP_RESSOURCE RESSOURCE_OPERATEUR, PENSOINS.ACTE_RDV_RESA ACTE_RDV_RESA
WHERE
RESSOURCE_OPERATEUR.ID_RESSOURCE=ACTE_RDV_RESA.REF_RESSOURCE
AND
RESSOURCE_OPERATEUR.REF_TYPE_RESSOURCE=1
)  TD_RESSOURCE_OPERATEUR,
PENSOINS.EJ_SRV  RDV_SRV,
PENSOINS.VENUE,
(
SELECT A.NIACTERDV, A.NIVENUE, TD.NISEJMOUV, V.NIPATIENT, nvl(TD.NISEJOUR, V.NISEJOUR) as NISEJOUR, V.NISERVICE
FROM PENSOINS.ACTE_RDV  A,
PENSOINS.VENUE      V,
(
SELECT L.NIACTERDV, L.NIVENUE, DER.DATE_DER_MAJ, L.NISEJMOUV, M.NISEJOUR
FROM PENSOINS.LIEN_RDV_MVT L,
PENSOINS.MOUVEMEN     M,
(
SELECT A.NIACTERDV, A.NIVENUE, max(nvl(L.DATE_MODIF, L.DATE_CREA)) DATE_DER_MAJ
FROM PENSOINS.ACTE_RDV     A,
PENSOINS.LIEN_RDV_MVT L
WHERE A.NIACTERDV = L.NIACTERDV
AND L.RETRAIT = 'F'
GROUP BY A.NIVENUE,A.NIACTERDV
) DER
WHERE L.NISEJMOUV = M.NISEJMOUV
AND DER.NIACTERDV = L.NIACTERDV
AND DER.NIVENUE = L.NIVENUE
AND DER.DATE_DER_MAJ = nvl(L.DATE_MODIF, L.DATE_CREA)
AND L.RETRAIT = 'F'
) TD
WHERE A.NIVENUE(+) = V.NIVENUE
AND TD.NIACTERDV(+) = A.NIACTERDV
)  TD_VENUE,
PENSOINS.PATIENT  PATIENT_SOIGNE
WHERE
( PENSOINS.ACTE_RDV.STATUTRDV=RDV_STATUT.NI(+)  )
AND  ( PENSOINS.ACTE_RDV_GRP.NIACTERDV=PENSOINS.ACTE_RDV.NIACTERDV  )
AND  ( S_ACTE_MED.NIACTE=PENSOINS.ACTE_RDV_GRP.NIACTE and S_ACTE_MED.NISERVICE=PENSOINS.ACTE_RDV_GRP.NISERVICE  )
AND  ( OPERATEUR.NIUTILISAT(+)=TD_RESSOURCE_OPERATEUR.ID_DXCARE  )
AND  ( TD_RESSOURCE_OPERATEUR.NIACTERDV(+)=PENSOINS.ACTE_RDV.NIACTERDV  )
AND  ( PENSOINS.ACTE_RDV.NISERVICE=RDV_SRV.NISERVICE(+)  )
AND  ( PENSOINS.VENUE.NIVENUE=TD_VENUE.NIVENUE  )
AND  ( TD_VENUE.NIACTERDV=PENSOINS.ACTE_RDV.NIACTERDV(+)  )
AND  ( PATIENT_SOIGNE.NIPATIENT(+)=PENSOINS.VENUE.NIPATIENT  )
AND  RDV_STATUT.CODE|| ' - ' ||RDV_STATUT.LIBELLE  IN  ( 'R - Attribué','M - Modifié'  )
AND  RDV_SRV.CODE||' - '||RDV_SRV.NOM  IN  ( '07 - Diététique','08 - Endocrinologie','18 - Oncologie','19 - Ophtalmologie','24 - Pneumologie','30 - Rhumatologie','34 - Orthophonie','40 - Consultations externes','42 - Stomatologie','43 - HOPITAL DE JOUR MEDECINE','44 - Hématologie','20 - ORL','CE 02 - Anesthésie','CE 03 - Cardiologie','CE 04 - Chirurgie Orthopédique','CE 06 - Chirurgie Urologique','CE 07 - Chirurgie Viscérale','CE 08 - Hépato-gastro-entérologie','CE 09 - Chirurgie Plastique','CE 10 - Gériatrie','CE 11 - Gynécologie-Obstétrique','CE 12 - Médecine interne','CE 14 - Pédiatrie','CE 15 - Tabacologie','CE 16 - Chirurgie Vasculaire','16 - Néphrologie'  )
AND  substr(PENSOINS.ACTE_RDV.HORAIRE, 1, 8)  =  '".$date_next."'
GROUP BY
PATIENT_SOIGNE.NOM,
PATIENT_SOIGNE.PATRONYME,
PATIENT_SOIGNE.PRENOM,
to_date(PATIENT_SOIGNE.DATENAIS,'YYYYMMDD'),
decode(PATIENT_SOIGNE.SEXE,'F','Femme','M','Homme','Inconnu'),
PATIENT_SOIGNE.NIP,
S_ACTE_MED.CODEP1 || ' - ' || ( S_ACTE_MED.LIBELLE ),
OPERATEUR.NOM,
OPERATEUR.PRENOM";

使用它的代码:

$date_next = date_next_day();
$db_o = connexion_oracle_dxcare();
$parsed = oci_parse($db_o, $sql);
$ru=oci_execute($parsed);
if (!$ru) { //doesn't show anything
$e = oci_error($parsed);
print htmlentities($e['message']);
print "n<pre>n";
print htmlentities($e['sqltext']);
printf("n%".($e['offset']+1)."s", "^");
print  "n</pre>n";
}
$num_rows = oci_fetch_all($parsed, $res); //returns 0 rows
var_dump($res); //show me all the column names but no datas inside

日期格式很好,我的函数返回这种格式"YYYYMMDD",它正在工作
var转储显示:

array(9) { ["NOM"]=> array(0) { } ["NOM_NAISSANCE"]=> array(0) { } ["PRENOM"]=> array(0) { } ["DDN"]=> array(0) { } ["SEXE"]=> array(0) { } ["NIP"]=> array(0) { } ["ACTE"]=> array(0) { } ["NOM_OPERATEUR"]=> array(0) { } ["PRENOM_OPERATEUR"]=> array(0) { } }

我肯定错过了什么,但我找不到。有什么想法吗?

编辑:

所以我测试了问题是否与口音有关,但这个请求:

SELECT PENSOINS.EJ_SRV.NOM from PENSOINS.EJ_SRV WHERE PENSOINS.EJ_SRV.NOM LIKE 'Dié%'

运行良好(即使之后在浏览器中显示为©(。

我更改了这个部分:

AND  substr(PENSOINS.ACTE_RDV.HORAIRE, 1, 8)  =  '".$date_next."'  
GROUP BY  
PATIENT_SOIGNE.NOM,  
PATIENT_SOIGNE.PATRONYME,  
PATIENT_SOIGNE.PRENOM,  
to_date(PATIENT_SOIGNE.DATENAIS,'YYYYMMDD'),  

多次使用一些to_char、trunk、to_date,但都不起作用。

关于日期,我能够发表以下声明:

SELECT PENSOINS.ACTE_RDV.HORAIRE from PENSOINS.ACTE_RDV WHERE substr(PENSOINS.ACTE_RDV.HORAIRE, 1, 8) = :date_test_bv  

工作。这里:date_test_bv是类似20140415的字符串的绑定变量
所以现在我回到

AND  RDV_SRV.CODE||' - '||RDV_SRV.NOM  IN  ( '07 - Diététique','08 - Endocrinologie','18 - Oncologie','19 - Ophtalmologie','24 - Pneumologie','30 - Rhumatologie','34 - Orthophonie','40 - Consultations externes','42 - Stomatologie','43 - HOPITAL DE JOUR MEDECINE','44 - Hématologie','20 - ORL','CE 02 - Anesthésie','CE 03 - Cardiologie','CE 04 - Chirurgie Orthopédique','CE 06 - Chirurgie Urologique','CE 07 - Chirurgie Viscérale','CE 08 - Hépato-gastro-entérologie','CE 09 - Chirurgie Plastique','CE 10 - Gériatrie','CE 11 - Gynécologie-Obstétrique','CE 12 - Médecine interne','CE 14 - Pédiatrie','CE 15 - Tabacologie','CE 16 - Chirurgie Vasculaire','16 - Néphrologie'  )  
AND  substr(PENSOINS.ACTE_RDV.HORAIRE, 1, 8)  =  :date_bv  
GROUP BY  
PATIENT_SOIGNE.NOM,
PATIENT_SOIGNE.PATRONYME,  
PATIENT_SOIGNE.PRENOM,  
to_date(PATIENT_SOIGNE.DATENAIS,'YYYYMMDD'),  
decode(PATIENT_SOIGNE.SEXE,'F','Femme','M','Homme','Inconnu'),  
PATIENT_SOIGNE.NIP,  
S_ACTE_MED.CODEP1 || ' - ' || ( S_ACTE_MED.LIBELLE ),  
OPERATEUR.NOM,  
OPERATEUR.PRENOM  

知道绑定的字符串日期会产生成功的结果,并且使用重音符号不是问题
我没有任何错误消息,也没有来自PHP或Oracle的错误消息,只是空行,就像我前面显示的var dump一样
当时我真的不明白问题出在哪里。

隐式日期转换负责大多数在不同客户端中工作不同的查询。日期格式默认为在系统级别设置的NLS_DATE_FORMAT值,但许多客户端将通过在session级设置参数来覆盖该值。

具体来说,这两个表达式可能存在问题:

substr(PENSOINS.ACTE_RDV.HORAIRE, 1, 8)  =  '".$date_next."
...
to_date(PATIENT_SOIGNE.DATENAIS,'YYYYMMDD')

许多人通过强制所有客户端更改设置来解决这些问题,但更好的永久解决方案是始终指定所需的格式,或者完全避免日期转换。假设这两列是日期值,那么将表达式重写为以下内容会更安全:

substr(to_char(PENSOINS.ACTE_RDV.HORAIRE, 1, 8), 'YYYYMMDD')  =  '".$date_next."'
...
trunc(PATIENT_SOIGNE.DATENAIS)

(我不确定PHP是如何工作的,可能有更好的方法将$date_next作为日期而不是字符串传递。(

另一个猜测是非ASCII字符串在某个地方引发了问题:

RDV_SRV.CODE||' - '||RDV_SRV.NOM  IN  ( '07 - Diététique', ...

查看select sql_fulltext from gv$sql where lower(sql_fulltext) like '%07 - Di%;的输出,以确保正确地将查询传递给Oracle。如果某些文件或进程不支持非ASCII字符,那么您可能需要存储以下Unicode字符串:

RDV_SRV.CODE||' - '||RDV_SRV.NOM  IN  ( '07 - Di'||unistr('0E9')|'t'||unistr('0E9')||'tique', ...

相关内容

最新更新