Writing Data to a Blob
Before you can create a new Blob and write data to it, you must do at least one of the following:
- Include Blob data in a row to be inserted into a table.
- Replace the data referenced by a Blob column of a row.
- Update the data referenced by a Blob column of a row.
- The entry in a Blob column of a row does not actually contain Blob data. Rather, it has a Blob ID referring to the data, which is stored elsewhere. So, to set or modify a Blob column, you need to set (or reset) the Blob ID stored in it. If a blob column contains a Blob ID, and you modify the column to refer to a different Blob (or to contain NULL), the Blob referenced by the previously stored Blob ID will be deleted during the next garbage collection.
- These operations all require the following steps:
- Prepare an appropriate DSQL statement. This will be an INSERT statement if you are inserting a new row into a table, or an UPDATE statement for modifying a row. Each of these statements will need a corresponding input XSQLDA structure for supplying parameter values to the statement at run time. The Blob ID of a new Blob will be one of the values passed.
- Create a new Blob, and write data into it.
- Associate the Blob ID of the new Blob with the Blob column of the table row by executing the UPDATE or INSERT statement.
- Note that you cannot update Blob data directly. If you want to modify Blob data, you must:
- Create a new Blob.
- Read the old Blob data into a buffer where you can edit or modify it.
- Write the modified data to the new Blob.
- Prepare and execute an UPDATE statement that will modify the Blob column to contain the Blob ID of the new Blob, replacing the old Blob’s Blob ID.
The sections below describe the steps required to insert, replace, or update Blob data.
- Preparing the UPDATE or INSERT Statement
- Creating a New Blob and Storing Data
- Associating the New Blob with the Blob Column
Contents
Preparing the UPDATE or INSERT Statement
To prepare an UPDATE or INSERT statement for execution, follow these steps:
- Elicit an UPDATE or INSERT statement string from the user or create one for inserting a row or updating the row containing the Blob column of interest. For example, the following statement is for updating the Blob column named PROJ_DESC in the row of the table, PROJECT, whose PROJ_ID field contains a value specified at run time:
- char *upd_str = "UPDATE PROJECT SET PROJ_DESC = ? WHERE PROJ_ID = ?";";
- As an example of an INSERT statement, the following inserts a new row containing values in four columns:
- char *in_str = "INSERT INTO PROJECT (PROJ_NAME, PROJ_DESC, PRODUCT,
- PROJ_ID) VALUES (?, ?, ?, ?)";
- char *in_str = "INSERT INTO PROJECT (PROJ_NAME, PROJ_DESC, PRODUCT,
- The remaining steps refer only to UPDATE statements, but the actions apply to INSERT statements as well.
- Declare a variable to hold the input XSQLDA needed to supply parameter values to the UPDATE statement at run time. For example, the following declaration creates an XSQLDA called in_sqlda:
- XSQLDA *in_sqlda;
- Allocate memory for the input XSQLDA using the XSQLDA_LENGTH macro. The XSQLDA must contain one XSQLVAR substructure for each parameter to be passed to the UPDATE statement. The following statement allocates storage for an input XSQLDA (in_sqlda) with two XSQLVAR substructures:
- in_sqlda = (XSQLDA *)malloc(XSQLDA_LENGTH(2));
- Set the version field of the XSQLDA to SQLDA_CURRENT_VERSION, and set the sqln field to indicate the number of XSQLVAR structures allocated:
- in_sqlda->version = SQLDA_CURRENT_VERSION;
- in_sqlda->sqln = 2;
- Set up the XSQLVAR structure in the XSQLDA for each parameter to be passed. Setting up an XSQLVAR structure involves the following steps:
- Specify the item’s datatype
- For parameters whose types are known at compile time: Point the sqldata field of the XSQLVAR to an appropriate local variable that will contain the data to be passed
- For parameters whose types are not known until run time: Allocate local storage for the data pointed to by the sqldata field of the XSQLVAR
- Specify the number of bytes of data
- #define PROJLEN 5
- char proj_id[PROJLEN + 1];
- ISC_QUAD blob_id;
- in_sqlda->sqlvar[0].sqldata = (char *) &blob_id;
- in_sqlda->sqlvar[0].sqltype = SQL_Blob + 1;
- in_sqlda->sqlvar[0].sqllen = sizeof(ISC_QUAD);
- in_sqlda->sqlvar[1].sqldata = proj_id;
- in_sqlda->sqlvar[1].sqltype = SQL_TEXT;
- in_sqlda->sqlvar[1].sqllen = 5;
Creating a New Blob and Storing Data
To create a new Blob containing the data to be written:
- Declare and initialize a Blob handle:
- isc_blob_handle blob_handle; /* Declare a Blob handle. */
- blob_handle = NULL;/* Set handle to NULL before using it */
- Declare and initialize a Blob ID:
- ISC_QUAD blob_id; /* Declare a Blob ID. */
- blob_id = NULL; /* Set handle to NULL before using it */
- Create a new Blob by calling isc_create_blob2():
- isc_create_blob2(status_vector, &db_handle, &trans,
- &blob_handle, /* set by this function to refer to the new Blob */
- &blob_id, /* Blob ID set by this function */
- 0, /* Blob Parameter Buffer length = 0; no filter will be used */
- NULL); /* NULL Blob Parameter Buffer, since no filter will be used */
- isc_create_blob2(status_vector, &db_handle, &trans,
- Write all the data to be written to the Blob by making a series of calls to isc_put_segment(). The following example reads lines of data, and concatenates each to the Blob referenced by blob_handle. (get_line() reads the next line of data to be written.)
- char *line;
- unsigned short len;
- . . .
- line = get_line();
- while (line) {
- len = strlen(line);
- isc_put_segment(status_vector,
- &blob_handle, /* set by previous isc_create_blob2() */
- len, /* length of buffer containing data to write */
- line); /* buffer containing data to write into Blob */
- if (status_vector[0] == 1 && status_vector[1]) {
- isc_print_status(status_vector);
- return(1);
- };
- line = get_line();
- Close the Blob:
- isc_close_blob(status_vector, &blob_handle);
Associating the New Blob with the Blob Column
Execute the UPDATE statement to associate the new Blob with the Blob column in the row selected by the statement:
- isc_dsql_execute_immediate(status_vector, &db_handle, &trans,
- 0, /* indicates string to execute is null-terminated */
- upd_str, /* UPDATE statement string to be executed */
- 1, /* da_version number */
- in_sqlda); /* XSQLDA supplying parameters to UPDATE statement */