我遇到一个问题,我有一个请求在带有oracle DB
插件的SQL Developer
或VsCode
中工作,但在php代码中,它返回0行PHP
版本很旧,对此我无能为力,5.4.6,OracleDB
是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', ...