从 SQL 进行操作系统调用
2009-11-20 00:00:00 来源:WEB开发网对于我们的示例,假定文件有下列结构:
该文件由一系列统一的结构化记录组成。
每个记录总共包含 60 字节。
前 10 个字节包含(以文本表示的)32 位带符号的整数值。
后 50 个字节表示一个定长字符串。
从文件结构到关系结构的简单映射就是把文件中的所有记录作为一个具有两列的表返回。第一列的类型是 INTEGER,第二列的类型是 VARCHAR(50)。文件中的每个记录将成为表中的一行。注:其它文件可能采用不同的文件格式,每种格式都需要属于自己的专门映射。您需要为支持每种映射而实现单独的函数。
定义了映射之后,让我们创建数据库系统中的函数。 清单 5向您展示了创建的方法。
清单 5. 创建读取文件并将它表示为表的函数
CREATE FUNCTION readFileTable(fileName VARCHAR(256))
RETURNS TABLE ( intCol INTEGER, string VARCHAR(50) )
SPECIFIC readFileToTable
EXTERNAL NAME 'os_calls!readFileToTable'
LANGUAGE C
PARAMETER STYLE SQL
DETERMINISTIC
NOT FENCED
RETURNS NULL ON NULL INPUT
NO SQL
NO EXTERNAL ACTION
SCRATCHPAD
NO FINAL CALL
DISALLOW PARALLEL;
GRANT EXECUTE ON FUNCTION readFileTable TO PUBLIC;
清单 6展示了实现从文件格式到关系表映射的 C 代码。
清单 6. 将文件内容表示为表的 C 代码
#include <stdio.h>
#include <sqludf.h>
#include <sqlstate.h>
void SQL_API_FN readFileToTable(
SQLUDF_VARCHAR *fileName, /* input */
SQLUDF_INTEGER *intCol, /* output */
SQLUDF_VARCHAR *charCol, /* output */
/* null indicators */
SQLUDF_NULLIND *fileName_ind,
SQLUDF_NULLIND *intCol_ind,
SQLUDF_NULLIND *charCol_ind,
SQLUDF_TRAIL_ARGS_ALL)
{
size_t readCnt = 0;
char intValue[10+1] = { '\\0' };
char strValue[50+1] = { '\\0' };
struct scratchMap {
FILE *f;
int rowNumber;
};
/* map the scratchpad */
struct scratchMap *scratch =
(struct scratchMap *)SQLUDF_SCRAT->data;
*intCol_ind = -1;
*charCol_ind = -1;
switch (SQLUDF_CALLT) {
case SQLUDF_TF_OPEN:
/* open file and store the pointer on the scratchpad */
scratch->f = fopen(fileName, "r");
if (!scratch->f) {
strcpy(SQLUDF_MSGTX, "Could not open file ");
strncat(SQLUDF_MSGTX, fileName, SQLUDF_MSGTEXT_LEN -
strlen(SQLUDF_MSGTX)-1);
strncpy(SQLUDF_STATE, "38200", SQLUDF_SQLSTATE_LEN);
return;
}
scratch->rowNumber = 0;
break;
case SQLUDF_TF_FETCH:
/* count the row */
scratch->rowNumber++;
/* read the integer */
readCnt = fread(intValue, 1, 10, scratch->f);
if (readCnt == 0) {
/* end of file reached */
/* end of file reached */
strncpy(SQLUDF_STATE, SQL_NODATA_EXCEPTION,
SQLUDF_SQLSTATE_LEN);
return;
}
else if (readCnt != 10) {
sprintf(SQLUDF_MSGTX, "Could not read int value "
"in line %d", scratch->rowNumber);
strncpy(SQLUDF_STATE, "38201", SQLUDF_SQLSTATE_LEN);
return;
}
intValue[10] = '\\0';
if (sscanf(intValue, "%d", intCol) != 1) {
sprintf(SQLUDF_MSGTX, "Invalid integer value %s "
" in row %d", intValue, scratch->rowNumber);
strncpy(SQLUDF_STATE, "38202", SQLUDF_SQLSTATE_LEN);
return;
}
*intCol_ind = 0;
/* read the string (allow truncations at EOF) */
readCnt = fread(strValue, 1, 50, scratch->f);
strValue[readCnt] = '\\0';
strcpy(charCol, strValue);
*charCol_ind = 0;
break;
case SQLUDF_TF_CLOSE:
/* close the file */
fclose(scratch->f);
scratch->f = NULL;
scratch->rowNumber = 0;
}
}
- ››sql server自动生成批量执行SQL脚本的批处理
- ››sql server 2008亿万数据性能优化
- ››SQL Server 2008清空数据库日志方法
- ››sqlserver安装和简单的使用
- ››SQL Sever 2008 R2 数据库管理
- ››SQL SERVER无法安装成功,sqlstp.log文件提示[未发...
- ››Sql Server中通过父记录查找出所有关联的子记录
- ››SqlServer触发器、存储过程和函数
- ››SQL Server 中的事务(含义,属性,管理)
- ››Sqlite数据库插入和读取图片数据
- ››Sql server 2005拒绝了对对象 'xx表' (数...
- ››Sql server 2005拒绝了对对象 'xx表' (数...
更多精彩
赞助商链接