Sql 类型参数的标识符无效

Sql 类型参数的标识符无效,sql,oracle,plsql,Sql,Oracle,Plsql,我正在尝试执行一个简单的查询,以获取包含从一个SDO_几何体到另一个SDO_几何体的距离的距离列 我的代码如下 DECLARE query VARCHAR(4000); L_LATITUDE number; L_LONGITUDE number; BEGIN IF :P7_USER_POSTCODE IS NOT NULL THEN brian.GEOCODE_GM_JSON (:P7_USER_POSTCODE, L_LATITUDE, L_LONGITUDE); END IF;

我正在尝试执行一个简单的查询,以获取包含从一个SDO_几何体到另一个SDO_几何体的距离的距离列

我的代码如下

DECLARE query VARCHAR(4000); L_LATITUDE number; L_LONGITUDE number;

BEGIN 
IF :P7_USER_POSTCODE IS NOT NULL THEN
    brian.GEOCODE_GM_JSON (:P7_USER_POSTCODE, L_LATITUDE, L_LONGITUDE);
END IF;


query :=     'SELECT 
                     S.SPOT_ID,
                     dbms_lob.getlength("THUMBNAIL") "THUMBNAIL",
                     IND.SPOT_NAME,
                     IND.SPOT_DESCRIPTION,
                     SPOT.POSTCODE
             FROM SPOT_IMAGES S
             INNER JOIN SURFSPOTINDEX IND ON IND.SPOT_ID = S.SPOT_ID
             INNER JOIN SPOT_LOCATION SPOT ON SPOT.SPOT_ID = IND.SPOT_ID';

IF :P7_SEARCH IS NULL AND :P7_USER_POSTCODE IS NULL THEN
    return query;


ELSIF :P7_SEARCH IS NOT null  AND :P7_USER_POSTCODE IS NULL THEN

    query := query || ' ' ||
          'WHERE CONTAINS(IND.SPOT_DESCRIPTION, :P7_SEARCH, 123) > 0
           OR UPPER(IND.SPOT_NAME) LIKE UPPER(''%'' || :P7_SEARCH || ''%'')
            ';

            RETURN query;


ELSIF :P7_SEARCH IS null  AND :P7_USER_POSTCODE IS NOT NULL THEN


        query :=     'SELECT 
                     S.SPOT_ID,
                     dbms_lob.getlength("THUMBNAIL") "THUMBNAIL",
                     IND.SPOT_NAME,
                     IND.SPOT_DESCRIPTION,
                     SPOT.POSTCODE,
                     ASDO_GEOM.SDO_DISTANCE(SPOT.LOCATION,
                                          SDO_GEOMETRY(2001,
                                          4326,
                                          SDO_POINT_TYPE(L_LONGITUDE, L_LATITUDE, null),
                                          null,
                                          null)
                     ,0.005, ''unit=mile'')   as DISTANCE
             FROM SPOT_IMAGES S
             INNER JOIN SURFSPOTINDEX IND ON IND.SPOT_ID = S.SPOT_ID
             INNER JOIN SPOT_LOCATION SPOT ON SPOT.SPOT_ID = IND.SPOT_ID
             ORDER BY Distance ASC';

          RETURN query;

END IF;

END;
最后一个else if是发生错误的地方

我得到了错误

 ORA-00904: "LONGITUDE": invalid identifier
我不明白为什么谷歌搜索了大量的错误代码。 GEOCODE_GM_JSON在输入变量中返回纬度和经度,我已经对此进行了测试,它工作正常

任何帮助都将不胜感激


谢谢。

您可以使用
DEFINE
来使用外部变量。然后将其用作查询中的
&variable\u name

DEFINE LATITUDE = 50.5261556;
DEFINE LONGITUDE = -5.5261556;


SELECT 
                 S.SPOT_ID,
                 dbms_lob.getlength("THUMBNAIL") "THUMBNAIL",
                 IND.SPOT_NAME,
                 IND.SPOT_DESCRIPTION,
                 SPOT.POSTCODE,
                 SDO_GEOM.SDO_DISTANCE(SPOT.LOCATION,
                                          SDO_GEOMETRY(2001,
                                          4326,
                                          SDO_POINT_TYPE(&LATITUDE, &LONGITUDE, null),
                                          null,
                                          null)
                     ,0.005, 'unit=mile') 
         FROM SPOT_IMAGES S
         INNER JOIN SURFSPOTINDEX IND ON IND.SPOT_ID = S.SPOT_ID
         INNER JOIN SPOT_LOCATION SPOT ON SPOT.SPOT_ID = IND.SPOT_ID;  

您可以使用
DEFINE
来使用外部变量。然后将其用作查询中的
&variable\u name

DEFINE LATITUDE = 50.5261556;
DEFINE LONGITUDE = -5.5261556;


SELECT 
                 S.SPOT_ID,
                 dbms_lob.getlength("THUMBNAIL") "THUMBNAIL",
                 IND.SPOT_NAME,
                 IND.SPOT_DESCRIPTION,
                 SPOT.POSTCODE,
                 SDO_GEOM.SDO_DISTANCE(SPOT.LOCATION,
                                          SDO_GEOMETRY(2001,
                                          4326,
                                          SDO_POINT_TYPE(&LATITUDE, &LONGITUDE, null),
                                          null,
                                          null)
                     ,0.005, 'unit=mile') 
         FROM SPOT_IMAGES S
         INNER JOIN SURFSPOTINDEX IND ON IND.SPOT_ID = S.SPOT_ID
         INNER JOIN SPOT_LOCATION SPOT ON SPOT.SPOT_ID = IND.SPOT_ID;  

您尚未显示完整的错误堆栈,并且消息似乎与您修改的代码不完全对应,但看起来您正在返回的查询字符串中嵌入字符串文字
L_LATITUDE
L_LONGITUDE
;但是,当调用方试图运行生成的代码时,这些变量对调用方没有任何意义

您可以在实际变量值中串联:

                     ASDO_GEOM.SDO_DISTANCE(SPOT.LOCATION,
                                          SDO_GEOMETRY(2001,
                                          4326,
                                          SDO_POINT_TYPE('
                                            || L_LONGITUDE ||', '|| L_LATITUDE
                                            ||', null),
                                          null,
                                          null)
                     ,0.005, ''unit=mile'')   as DISTANCE

尽管这意味着由于这些文本值,每个查询都必须进行硬解析。如果Apex在执行查询时可以引用该绑定变量,则返回邮政编码的SDO点(而不是纬度和经度)的另一个函数可能会更好—上一个分支中的查询使用
:P7_SEARCH
,表明它可以。这将删除连接,删除硬解析并减少SQL注入的可能性。

您还没有显示完整的错误堆栈,并且消息似乎与您修改的代码不完全对应,但是它看起来像是在返回的查询字符串中嵌入字符串文字
L\u LATITUDE
L\u LONGITUDE
;但是,当调用方试图运行生成的代码时,这些变量对调用方没有任何意义

您可以在实际变量值中串联:

                     ASDO_GEOM.SDO_DISTANCE(SPOT.LOCATION,
                                          SDO_GEOMETRY(2001,
                                          4326,
                                          SDO_POINT_TYPE('
                                            || L_LONGITUDE ||', '|| L_LATITUDE
                                            ||', null),
                                          null,
                                          null)
                     ,0.005, ''unit=mile'')   as DISTANCE


尽管这意味着由于这些文本值,每个查询都必须进行硬解析。如果Apex在执行查询时可以引用该绑定变量,则返回邮政编码的SDO点(而不是纬度和经度)的另一个函数可能会更好—上一个分支中的查询使用
:P7_SEARCH
,表明它可以。这将删除连接,删除硬解析并减少SQL注入的可能性。

前两行不是有效的SQL。要使用赋值,代码需要包装在PL/SQL块中。使用过程顶部的DECLARE在顶部定义参数,并使用用户定义的输入分配参数。但是,我在那里得到了相同的错误。调用此块或尝试运行返回的查询时是否发生错误?错误实际上指的是
经度
,还是
L_经度
?前两行不是有效的SQL。要使用赋值,代码需要包装在PL/SQL块中。使用过程顶部的DECLARE在顶部定义参数,并使用用户定义的输入分配参数。但是,我在那里得到了相同的错误。调用此块或尝试运行返回的查询时是否发生错误?错误实际上是指
经度
,还是
L_经度
?在生产代码中,参数在顶部使用DECLARE声明。代码位于APEX函数中,该函数返回一个查询,并且似乎不喜欢DEFINE关键字。不能传入声明的变量吗?@Nick如果使用
DECLARE
声明它,那么它必须是一个块。它不能是独立查询。显示其在生产中的完整代码。如果您试图使用
SQLPLUS
运行独立查询,那么上面所回答的肯定会起作用。我已经更改了问题中的代码,以便更清楚地了解我实际要做的事情。感谢在生产代码中,使用DECLARE在顶部声明参数。代码位于APEX函数中,该函数返回一个查询,并且似乎不喜欢DEFINE关键字。不能传入声明的变量吗?@Nick如果使用
DECLARE
声明它,那么它必须是一个块。它不能是独立查询。显示其在生产中的完整代码。如果您试图使用
SQLPLUS
运行独立查询,那么上面所回答的肯定会起作用。我已经更改了问题中的代码,以便更清楚地了解我实际要做的事情。Thanksame用于:从第一个查询开始的P7_搜索。我假设OP希望将值连接到查询,这是引入SQL注入的一种很好的方式……我相信Apex在执行生成的查询时仍然会绑定
:P7_SEARCH
。假设分支工作,这是隐含的。这里的问题似乎是通过一个过程转换为纬度/经度,而查询执行不能直接使用这个过程。如果这是正确的,那么注射风险取决于这里的转换程序?但是,指出串联的风险总是一个好主意。我对Apex的了解还不够,不知道这种方法是否有必要——看起来不太可能……这解决了我的问题,因为它只是简单地传回要执行的参数字符串而不是值。谢谢第一个查询中的:P7_搜索也是如此。我假设OP希望将值连接到查询,这是引入SQL注入的一种很好的方式……我相信Apex在执行生成的查询时仍然会绑定
:P7_SEARCH
。假设分支工作,这是隐含的。这里的问题似乎是通过一个过程转换为纬度/经度,而查询执行不能直接使用这个过程。如果这是正确的,那么注射风险取决于这里的转换程序?但是是的,指出了concaten的风险