使用Rust-odbc_api在SQL Server中编写varchar(max)列类型时出现问题



我正在Rust中使用混合列类型的odbc_api从sql数据库中读取一些数据。但是,我注意到表中具有varchar(max)的字段无法从表中返回。我认为这与TextRowSet字符串缓冲区大小有关,但即使我将值从4 KiB更改为更高的限制,我仍然无法收到varchar列。一切构建都没有警告或错误。

代码:

use anyhow::Error;
use odbc_api::{buffers::TextRowSet, Cursor, Environment, ResultSetMetadata};
use std::io;
const BATCH_SIZE: usize = 100;
fn main() -> Result<(), Error> 
{   
// Write sql query to stdout
let out = io::stdout();
let mut writer = csv::Writer::from_writer(out);
// Establish environment
let environment = Environment::new()?; 
let connection_string = "
Driver={ODBC Driver 17 for SQL Server};
Server=my_server;
db=my_db;
trusted_connection=yes;
";
let conn = environment.connect_with_connection_string(connection_string)?;

// Set up query and execute
let qry = "select top 10 * from my_tbl";
match conn.execute(&qry, ())
{
Err(e) => println!("{}", e),
Ok(Some(mut cursor)) => {
// Write column names to stdout
let headline: Vec<String> = cursor.column_names()?.collect::<Result<_,_>>()?;
writer.write_record(headline)?;

// Use schema in cursor to initialize a text buffer large enough to hold the largest
// possible strings for each column to an upper limit of 4Kib.
let mut buffers = TextRowSet::for_cursor(BATCH_SIZE, &mut cursor, Some(4096))?;
// Bind the buffer to the cursor. It will now be filled with every call to fetch.
let mut row_set_cursor = cursor.bind_buffer(&mut buffers)?;
// Iterate over batches
while let Some(batch) = row_set_cursor.fetch()?
{   
// Within a batch, iterate over every row
for row_index in 0..batch.num_rows()
{
//println!("{}", row_index);
let record = (0..batch.num_cols()).map(|col_index| {
batch.at(col_index, row_index)
.unwrap()
});
// Writes row as csv
writer.write_record(record)?;
}
}
},
Ok(None) => {
eprintln!("Query came back empty. No output created.");
}
}
Ok(())
}

odbc_api文档:https://docs.rs/odbc-api/latest/odbc_api/

**破解解决方案编辑:**

因此,通过转到源表并将字段varchar(max)修改为varchar(255),我有效地解决了这个问题。有人能解释一下这里发生了什么吗?

Microsoft SQL Server报告类型为VARCHAR(max)的列的元素大小为0。文本缓冲区为每个字段分配刚好足够的内存用于终止零,同时保持在指定的上限之下。由于我是odbc-api的作者,我在阅读了你的问题后发布的0.50.2版本中修复了它。

最新更新