【问题标题】:Inserting large text into blob将大文本插入 blob
【发布时间】:2014-12-12 08:23:51
【问题描述】:

长期以来,我一直在努力寻找解决此问题的方法,但在互联网上无处可找到答案。我有这种情况,我需要使用 php 从 firebird 数据库中插入或更新 blob 字段(子类型 1)。问题是当文本变得非常大 >36k 时,它不会执行查询。我知道行查询仅限于 32k 的数据,我尝试在 c# 中使用参数化查询,但我无法在 PHP 中找到适合我的东西。甚至离工作不近。

我尝试使用ibase_blob_Create 等我尝试直接插入Insert into table (blob_value) values (?)ibase_prepare 等。似乎没有什么对我有用。是否有一些神奇的方法可以在 php 中完成这项工作,还是无法将大文本从 php 转换为 blob?

我试过使用类似的东西:

class DBMgmt_Ibase_Blob extends DBMgmt_Generic_Blob
{
var $blob; // resourse link
var $id;
var $database;

function DBMgmt_Ibase_Blob(&$database, $id=null)
{
    $this->database =& $database;
    $this->id = $id;
    $this->blob = null;
}

function read($len)
{
    if ($this->id === false) return ''; // wr-only blob
    if (!($e=$this->_firstUse())) {
        return $e;
    }

    $data = @ibase_blob_get($this->blob, $len);
    if ($data === false) return $this->_setDbError('read');
    return $data;        
}

function write($data)
{
    if (!($e=$this->_firstUse())) return $e;
    $ok = @ibase_blob_add($this->blob, $data);
    if ($ok === false) return $this->_setDbError('add data to');
    return true;
}

function close()
{
    if (!($e=$this->_firstUse())) return $e;
    if ($this->blob) {
        $id = @ibase_blob_close($this->blob);
        if ($id === false) return $this->_setDbError('close');
        $this->blob = null;
    } else {
        $id = null;
    }
    return $this->id ? $this->id : $id;
}

function length()
{
    if ($this->id === false) return 0; // wr-only blob
    if (!($e=$this->_firstUse())) return $e;
    $info = @ibase_blob_info($this->id);
    if (!$info) return $this->_setDbError('get length of');
    return $info[0];
}

function _setDbError($query)
{
    $hId = $this->id === null ? "null" : ($this->id === false ? "false" : $this->id);
    $query = "-- $query BLOB $hId"; 
    $this->database->_setDbError($query);        
}

// Called on each blob use (reading or writing).
function _firstUse()
{
    // BLOB is opened - nothing to do.
    if (is_resource($this->blob)) return true;
    // Open or create blob.
    if ($this->id !== null) {
        $this->blob = @ibase_blob_open($this->id);
        if ($this->blob === false) return $this->_setDbError('open'); 
    } else {
        $this->blob = @ibase_blob_create($this->database->link);
        if ($this->blob === false) return $this->_setDbError('create');
    }
    return true;
}
}

我是这样使用的:

 $text = new DBMgmt_Ibase_Blob($DB);
            if (!$text->write(htmlspecialchars($Data["Text"]))){
                throw new Exception("blob fail");
            }
  $blobid = $text->close();
  //similar query
$DB->query("INSERT INTO TABLE1 (BLOB_VALUE) VALUES (?)",$blobid);

在那之后,我在我的数据库中找到了一个我知道我必须使用的数字:

Blob = new DBMgmt_Ibase_Blob($DB,$data->Text);
    $data->Text = $Blob->read($Blob->length());

但我得到 String is not a BLOB ID with a number in database like 30064771072.

我尝试直接添加它,但它当然不会像这样工作

$DB->query('insert into table (blob) values (?)',$string); // where string is like 170k chars

我得到 Dynamic SQL Error SQL 错误代码 = -104 Unexpected end of command - line 1, column 236

我尝试将其放入 php.net 参考 php.net blob_import 之后的文件中,代码类似于:

$dbh = ibase_connect($host, $username, $password);
$filename = '/tmp/bar';

 $fd = fopen($filename, 'r');
if ($fd) {

$blob = ibase_blob_import($dbh, $fd);
fclose($fd);

if (!is_string($blob)) {
    // import failed
} else {
    $query = "INSERT INTO foo (name, data) VALUES ('$filename', ?)";
    $prepared = ibase_prepare($dbh, $query);
    if (!ibase_execute($prepared, $blob)) {
        // record insertion failed
    }
}
} else {
// unable to open

但我仍然得到像 blob 写入方法一样的结果。

【问题讨论】:

  • 不知道firebird,但也许创建一个文件并导入它会起作用。这是大型 mysql 查询的常见问题 (LOAD DATA INFILE)
  • 显示您尝试过的一些代码,以及您遇到的错误。另外,搜索“Firebird PHP large queries”turned this up as like the 4th hit.您使用的是什么版本的 PHP?
  • Firebird 应该有一个执行 SQL 脚本的选项,这与执行查询不同。将庞大的查询作为 SQL 脚本执行应该不会有任何问题。
  • 问题是我尝试用php来做,我不知道为什么我写的时候问题没有包含它,但它是关于php的。
  • @AnchovyLegend 在 firebird 2.5 及更早版本中,语句文本的最大长度为 64 KB,参数的最大总长度为 32 KB(其中 blobid 仅为 8 字节)

标签: php sql blob firebird


【解决方案1】:

你需要使用参数:

$query = ibase_prepare($DB, 'insert into table (blob) values (?)');
ibase_execute($query, $string);

cf : http://php.net/manual/en/function.ibase-execute.php

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-16
    • 2014-11-26
    • 1970-01-01
    • 2020-04-21
    • 2014-09-09
    • 2016-08-15
    • 1970-01-01
    相关资源
    最近更新 更多