我正在尝试使用Npgsql来调用以CHARACTER作为参数的函数(存储过程),但它不起作用。如果我声明没有参数的相同函数,或者使用INTEGER参数,我会得到我想要的结果集。当我将参数声明为CHARACTER时,它将停止工作。有什么问题?
以下是我的功能代码:
CREATE OR REPLACE FUNCTION testrefcursor1(in xxx character varying(10)) RETURNS SETOF refcursor AS
$$
DECLARE
ref1 refcursor;
ref2 refcursor;
BEGIN
OPEN ref1 FOR
SELECT * FROM accounts;
RETURN NEXT ref1;
OPEN ref2 FOR
SELECT * FROM accounts;
RETURN NEXT ref2;
RETURN;
END;
$$
LANGUAGE plpgsql;
以下是我正在使用的C#代码:
var connection = new Npgsql.NpgsqlConnection(connectionString.ConnectionString);
connection.Open();
var trans = connection.BeginTransaction();
var command = new Npgsql.NpgsqlCommand("testrefcursor1", connection);
command.CommandType = System.Data.CommandType.StoredProcedure;
var parameter = command.CreateParameter();
parameter.ParameterName = "xxx";
parameter.DbType = System.Data.DbType.String;
parameter.Value = "10";
command.Parameters.Add(parameter);
var da = new Npgsql.NpgsqlDataAdapter(command);
var ds = new System.Data.DataSet();
da.Fill(ds);
trans.Commit();
connection.Close();
我已经尝试将参数声明为CHARACTER,CHARACTER(10),CHARACTER VARYING和CHARACTER VARYING(10)......
编辑:我没有得到任何错误消息,但是我没有得到预期的结果集,而是获得一个空的结果集,其中包含一个与我试图调用的函数同名的列。答案 0 :(得分:5)
您正在将Unicode参数传递给ASCII参数。
更改此行:
parameter.DbType = System.Data.DbType.String;
要:
parameter.DbType = System.Data.DbType.AnsiString;
通常,Postgres的varchar
列是Unicode格式,前提是数据库上的Unicode选项已启用(see here)。我的猜测是,它不是,并且您的参数无法将自身转换为正确的类型以通过该函数传递。
答案 1 :(得分:2)
您使用的是哪个Npgsql版本?
另外,您可以使用NpgsqlDbType指定参数类型吗?有时映射不完全,Npgsql找不到您尝试使用的功能,无法使其正常工作。
Npgsql尝试查找函数名称和参数类型的完全匹配。 DbString匹配文本参数类型。您是否介意尝试将参数类型更改为文本?
我希望它有所帮助。
答案 2 :(得分:1)
不确定,如果这与您的问题有关,但昨天我偶然发现了fact PostgreSQL有一个“单字节内部类型”字符,它与char(1)类型不同。也许这些有些混乱?
答案 3 :(得分:0)
我尝试了以下方法(与您的类似):
<template>
<div>
<form class="form-horizontal">
<h2 class="text-center"> Table </h2>
<div class="form-group">
<div class="col-md-1">
<button @click="changeView('appTableStyle')" type="button" class="form-control btn btn-xs btn-warning">
<span class="glyphicon glyphicon-pencil"></span>
</button>
</div>
<label for="rows" class="control-label col-md-1">style:</label>
<div class="col-md-6">
<select class="form-control" v-model="table.tableStyle">
<option v-for="(item,key) in tableStyles" :value="item.Id">
{{ item.style }}
</option>
</select>
</div>
</div>
<div class="form-group">
<label for="rows" class="control-label col-md-2">rows:</label>
<div class="col-md-2">
<input type="number" min="1" v-model="table.rows" class="form-control" id="rows">
</div>
<label for="columns" class="control-label col-md-1">columns:</label>
<div class="col-md-2">
<input type="number" min="1" v-model="table.cols" class="form-control" id="cols">
</div>
<label for="columns" class="control-label col-md-2">How Many?:</label>
<div class="col-md-2">
<input type="number" min="1" v-model="insert" class="form-control" id="cols">
</div>
</div>
<table class="table table-responsive" style="background-color:lightGray">
<tbody>
<tr v-for="(row,idx2) in tableRows">
<td v-model="table.colsArr[idx]" :key="" class="table-success" v-for="(col,idx) in tableCols" contenteditable="true">{{idx}}</td>
</tr>
</tbody>
</table>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-9">
<div class="text-center">
<button type="submit" @click.prevent="addTable" class="btn btn-success margin-above2 btn-block">Add Table</button>
</div>
</div>
</div>
</form>
</div>
</template>
<script>
export default {
name: 'app',
data () {
return {
table: {
rows: 1,
cols: 1,
key: 'Table',
tableStyle: 1,
colsArr: []
},
insert: 1
}
},
methods: {
},
changeView: function (view) {
this.$store.commit('changeCurrentView', view)
}
},
computed: {
tableStyles () {
return this.$store.getters.getTableStyles
},
tableRows () {
return parseInt(this.table.rows)
},
tableCols () {
return parseInt(this.table.cols)
}
}
}
</script>
这对我来说很好,我得到了正确的DataTable。