现在要在一条记录的longblob字段中存放一段音频的数据(假设6M)
每次写入8K,需要写八百多次,每一次新写入的数据要追加到前面写入内容的后面。使最后从数据库取出来时这个文件仍然可以播放。一般都有些什么办法进行这种追加啊?我找到有地方说用update和concat来实现。 
但像下面的:
 sprintf(query,"update table table_name set blob_data=CONCAT(blob_data,'%s')",buffer); mysql_real_query(...,query, ... );是不行的,写完以后数据库的 blob_data 字段为 NULL, 
我看到资料上说 CONCAT函数 当其任何一个参数为NULL的时候就会返回NULL, 但是: 
我试过不是每次追加,而是每次将buffer中的8k insert到不同的记录中,然后将它们读出来放到一个文件中,得到的文件是和放入数据库中以前的文件相同的。就是说每个8K的数据都是可以INSERT并且正确读出来的。
所以不知道为什么在update的时候会出现 NULL的情况, 或者还有什么其它可能的原因呢? 

解决方案 »

  1.   

    #include <mysql.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>int main( int argc, char **argv) 
    {
      int insert_id;
      char *query;
      int datasize;
      MYSQL *demo_db = ( MYSQL * )malloc( sizeof(MYSQL) );
      MYSQL_RES *res;
      MYSQL_ROW row;
      unsigned long *lengths=(unsigned long *)malloc(10*sizeof(unsigned long));   /* Database Inition */
      mysql_init(demo_db);  
      /* connect to database */
      if (!mysql_real_connect(demo_db,"jz","root","","video", 3306, NULL, 0)) 
      {
        printf( mysql_error( demo_db ) );
        exit( 1 );
      }
      if ( mysql_select_db( demo_db, "video" ) ) {   // video 是数据库名
        printf( mysql_error( demo_db ) );
        exit( 1 );
      }
      
    #define BLOCKSIZE 8000     // 每次读入的长度
     /* Read data from a file and Store it into DB */  FILE *fp;
      if ( !( fp = fopen( "/home/jz/asdf", "r" ) ) )
    printf("open error");   char *data;  /* the buffer to store data that are read from the file */
      char *data2; /* after being added slash, data are stored in this buffer */   int seq = 1;
      int rdnum = 0; /* byte number read from the file */
      while ( !feof(fp) && !ferror(fp) )
      {        /* read data from a file */
    data = malloc( BLOCKSIZE*sizeof(char) + 1 );
       rdnum = fread( data, sizeof(char), BLOCKSIZE, fp );
        
            /* store data into database */
       data2 = ( char * )malloc( 2*rdnum  ); datasize = mysql_real_escape_string(demo_db, data2, data, rdnum ); query = malloc((3*datasize+255)*sizeof(char)); sprintf(query, "INSERT INTO videostream(V_no,number,data) VALUES(%d,%d,'%s')", 1, seq++, data2);   if (mysql_real_query(demo_db, query, strlen(query))) 
    {
         printf(mysql_error(demo_db));
         exit(1);
       }   free(query);
    free( data );
      free( data2 );  }// end of while  fclose(fp);   /* After read, close the file */
      /* Read data from the database */  query = ( char * ) malloc( 255*sizeof(char) );  sprintf(query, "SELECT * FROM videostream");
      if (mysql_real_query(demo_db, query, 255))
      {
        printf(mysql_error(demo_db));
        exit(1);
      }  res = mysql_use_result( demo_db );  fp = fopen("/home/jz/adfs","w");
       while( row = mysql_fetch_row( res ) ) 
       {
         lengths = mysql_fetch_lengths(res);
         fwrite( row[2], sizeof(char), (int)(lengths[2]), fp );
       }  fclose(fp);
      mysql_free_result(res);  mysql_close(demo_db);  return 0; 
    }
      

  2.   

    用concat时候使用ifnull先判断试试
      

  3.   

    klan 的方法我试过了,不行。那样写完以后会少东西,就是说原来的文件,写入数据库再读出之后文件大小会变小。丢掉了原文件中的东西。楼上说的也不行,因为目的就是要从一个好几个G的文件中分批读出来,使每次写入的量比较小,通过多次写入来测试数据库的性能。 那样每次进行文件操作是没有意义的各位还有别的建议吗?
    这种大段写追加应该有一种标准的写法吧。这也算是很正常的需求啊。sql语句应该有这种功能的支持吧。
      

  4.   

    在默认情况下,MySQL创建的MyISAM表允许的最大尺寸为4GB
    一个好几个G的文件恐怕不太现实.
      

  5.   

    所以不知道为什么在update的时候会出现 NULL的情况, 或者还有什么其它可能的原因呢? ---------
    看看你的原数据有没有问题。