使用npgsql调用以字符作为参数的函数

时间:2009-08-19 22:16:27

标签: c# database postgresql mono npgsql

我正在尝试使用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)......

编辑:我没有得到任何错误消息,但是我没有得到预期的结果集,而是获得一个空的结果集,其中包含一个与我试图调用的函数同名的列。

4 个答案:

答案 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>&nbsp;
          </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。