使用php在oracle数据库中插入数据

时间:2010-01-22 17:27:34

标签: php oracle

以下代码正在生成此

Warning: oci_execute() [function.oci-execute]: 
ORA-00911: invalid character in F:\wamp\www\SEarch Engine\done.php  on line 17

代码是......

<?php
include_once('config.php');
$db = oci_new_connect(ORAUSER,ORAPASS,"localhost/XE");

$url_name=$_POST['textfield'];
$keyword_name=$_POST['textarea'];
$cat_news=$_POST['checkbox'];
$cat_sports=$_POST['checkbox2'];
$anchor_text=$_POST['textfield2'];
$description=$_POST['textarea2'];

$sql1="insert into URL(Url_ID,Url_Name,Anchor_Text,Description) 
    VALUES( 9,".'{$url_name}'.",".'{$anchor_text}'.",".'{$description}'.")";



$result=oci_parse($db,$sql1);
oci_execute($result);





?>

6 个答案:

答案 0 :(得分:13)

永远不要将用户输入直接插入SQL。使用oci_bind_by_name()准备安全声明。作为一个副作用,这也将修复你得到的错误(这是一个引用错误)。代码看起来像

$url_name = $_POST['textfield'];
$anchor_text = $_POST['textfield2'];
$description = $_POST['textfield3'];

$sql = 'INSERT INTO URL(Url_ID,Url_Name,Anchor_Text,Description) '.
       'VALUES(9, :url, :anchor, :description)';

$compiled = oci_parse($db, $sql);

oci_bind_by_name($compiled, ':url', $url_name);
oci_bind_by_name($compiled, ':anchor', $anchor_text);
oci_bind_by_name($compiled, ':description', $description);

oci_execute($compiled);

答案 1 :(得分:1)

你在这里遇到了一些问题。首先,变量不会插入用单引号括起来的字符串中。试试这个简单的脚本来看看我的意思:

$a = 'hi';
print 'Value: $a'; // prints 'Value: $a'

VS。

$a = 'hi';
print "Value: $a"; // prints 'Value: hi'

其次,在使用变量构造SQL查询之前,您需要转义变量。任何POST变量中的单个“'”字符都会破坏您的查询,从而导致Oracle语法错误。

最后,也许最重要的是,我希望这只是示例代码?您正在使用未经过滤的用户输入来构造SQL查询,使您对SQL注入攻击持开放态度。转义变量至少可以防止最恶劣的攻击,但是你仍然应该做一些验证。切勿使用“污染”数据构建查询。

答案 2 :(得分:0)

如果没有看到生成的SQL是什么样的,你发布的是什么字符集以及数据库正在使用什么字符集,那么很难说。

将未经过滤的用户内容拼接到SQL语句中并将其发送到数据库是一种灾难。虽然PHP中的其他数据库API具有转义功能,但IIRC无法使用它 - 您应该使用数据绑定。

下进行。

答案 3 :(得分:0)

您要插入的varchar字段周围需要单引号(我认为这是url_name,anchor_text和description)。您当前的单引号只是将这些值设为String但在Oracle中,varchar字段需要在它们周围加上单引号。试试这个:

$sql1="insert into URL(Url_ID,Url_Name,Anchor_Text,Description) VALUES( 9,'".'{$url_name}'."','".'{$anchor_text}'."','".'{$description}'."')";

我没有任何地方可以测试PHP,但是应该在你的值周围创建单引号。

因为你最终将在数据库上执行的sql看起来像这样:

insert into URL
(
 Url_ID,
 Url_Name,
 Anchor_Text,
 Description
) 
VALUES
( 
 9,
 'My Name',
 'My Text',
 'My Description'
)

主要文章Binding Variables in Oracle and PHP似乎已关闭,但这里是Google Cache Version,详细介绍了如何在PHP中绑定变量。你肯定希望这样做是为了1)性能和2)SQL注入的安全性。

另外,我的PHP有点生疏,但看起来你也可以这样做你原来的查询语句:

$sql1="insert into URL(Url_ID,Url_Name,Anchor_Text,Description) values ( 9, '$url_name', '$anchor_text', '$description')";

修改
此外,您需要转义从表单变量收到的数据中可能存在的任何单引号。在Oracle sql字符串中,您需要将单引号转换为2个单引号以转义它们。请参阅标题为“如何插入包含引号的字符串?”的here部分。

答案 4 :(得分:0)

这是因为您在查询字符串中有未引用的引号字符。试试这个:

$sql1="insert into URL(Url_ID,Url_Name,Anchor_Text,Description) 
  VALUES( 9,\".'{$url_name}'.\",\".'{$anchor_text}'.\",\".'{$description}'.\")";

答案 5 :(得分:0)

如果您仍在开发中,我建议您直接使用AdoDB代替oci_函数。

您的代码可以使用AdoDB重写,如下所示:

<?php
include_once('config.php');

$url_name=$_POST['textfield'];
$keyword_name=$_POST['textarea'];
$cat_news=$_POST['checkbox'];
$cat_sports=$_POST['checkbox2'];
$anchor_text=$_POST['textfield2'];
$description=$_POST['textarea2'];

//do db connection
$adodb =& ADONewConnection("oci8://ORAUSER:ORAPASS@127.0.0.1/XE");
if ( ! $adodb )
{
  die("Cannot connect to database!");
}
//set mode
$adodb->SetFetchMode(ADODB_FETCH_BOTH);

//data for insert
$tablename = 'URL';
$data['Url_ID'] = 9;
$data['Url_Name'] = $url_name;
$data['Anchor_Text'] = $anchor_text;
$data['Description'] = $description;

$result = $adodb->AutoExecute($tablename, $data, 'INSERT');
if ( ! $result )
{
  die($adodb->ErrorMsg());
  return FALSE;
}
//reaching this line meaning that insert successful

在上面的代码中,您只需要创建一个关联数组,并将列名作为键,然后为正确的列指定值。数据卫生由AdoDB自动处理,因此您无需为每列手动执行此操作。

AdoDB是多数据库库,因此您可以通过应用程序中的最小代码更改来更改数据库。