oracle 通过ASP.NET将数据插入数据库时出现“(ORA-02287)sequence number not allowed here”错误

4ioopgfo  于 12个月前  发布在  Oracle
关注(0)|答案(1)|浏览(121)

我的数据库中有一个型号为Box的表。我试图通过ASP.NET应用程序插入新数据及其ID。ID本身是从名为box_seq的序列生成的。
这是上下文类:

using ApiProject.Models;
using Microsoft.EntityFrameworkCore;

namespace ApiProject.Data
{
    public class GeneralContext: DbContext
    {
        public GeneralContext(DbContextOptions<GeneralContext> options): base(options) { }
        public DbSet<Box> BoxDatabase { get; set; } = default!;
        public long SetNewId()
        {
            var query = Database.SqlQueryRaw<long>("SELECT box_seq.nextval FROM dual");
            long id = query.Single();
            return id;
        }
    }
}

方法SetNewId()在控制器中被调用:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using ApiProject.Data;
using ApiProject.Models;
using ApiProject.Models.Requests;

namespace ApiProject.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class BoxesController: ControllerBase
    {
        …
        [HttpPost]
        public async Task<ActionResult<Box>> create(BoxRequest request)
        {
            if (_context.BoxDatabase == null)
            {
                return Problem("Entity set 'GeneralContext.BoxDatabase' is null.");
            }
            var result = new Box
            {
                Id = _context.SetNewId(),
                XLength = request.XLength,
                YLength = request.YLength,
                ZLength = request.ZLength,
            };
            _context.BoxDatabase.Add(result);
            await _context.SaveChangesAsync();

            return CreatedAtAction("Get", new { id = result.Id }, result);
        }
        …
    }
}

无法将ID添加到新数据中。它会返回如下错误:

(ora-02287) sequence number not allowed here

有像thisthis这样的解决方案,但它们涉及直接将下一个值插入到insert语句中,我不知道在ASP.NET中是否可行。还有一个this question案例使用ASP.NET,但问题只是来自错误的查询,我的问题已经遵循了那里的答案。此外,我还尝试了像这样的SetNewId()体的变体:

public long SetNewId()
        {
            var query = Database.SqlQuery<long>($"SELECT box_seq.nextval FROM dual;");
            long id = query.Single();
            return id;
        }
public long SetNewId()
        {
            var query = Database.SqlQuery<long>($"SELECT NEXT VALUE FROM box_seq;");
            long task = query.SingleAsync();
            long id = task.Result;
            return id;
        }

前者返回(ora-02287) sequence number not allowed here,而后者返回“缺少右括号”。与此同时,这:

public long SetNewId()
        {
            var query = Database.SqlQuery<long>("SELECT box_seq.nextval FROM dual;");
            long id = query.Single();
            return id;
        }

返回警告cannot convert from 'string' to 'System.FormattableString'
你的帮助将不胜感激。

k10s72fa

k10s72fa1#

我对ASP.NET一无所知。
然而,由于甲骨文涉及,一些建议(如果我可以的话)。
如果您的数据库版本支持,请使用identity列,并让Oracle为您生成值;在背景中,它仍然是一个序列

SQL> create table box
  2    (id      number generated always as identity,
  3     name    varchar2(20)
  4    );

Table created.

SQL> insert into box (name) values ('Littlefoot');

1 row created.

SQL> select * from box;

        ID NAME
---------- --------------------
         1 Littlefoot

SQL>

如果你不能(或不想)使用它,回到你自己的序列,这次作为列的默认值:

SQL> drop table box;

Table dropped.

SQL> create sequence box_seq;

Sequence created.

SQL> create table box
  2    (id     number default box_seq.nextval,
  3     name   varchar2(20)
  4    );

Table created.

SQL> insert into box (name) values ('Littlefoot');

1 row created.

SQL> select * from box;

        ID NAME
---------- --------------------
         1 Littlefoot

SQL>

还有一个选项,我们用于 ages 的选项,是有一个序列和一个数据库触发器,它将把它插入到一个表中:

SQL> drop table box;

Table dropped.

SQL> create table box
  2    (id    number,
  3     name  varchar2(20)
  4    );

Table created.

SQL> create or replace trigger trg_bi_box
  2    before insert on box
  3    for each row
  4  begin
  5    :new.id := box_seq.nextval;
  6  end;
  7  /

Trigger created.

SQL> insert into box (name) values ('Littlefoot');

1 row created.

SQL> select * from box;

        ID NAME
---------- --------------------
         2 Littlefoot             --> ID = 2 because I reused already 
                                      existing sequence from previous example

如果你的问题的解决方案必须涉及ASP.NET(我猜是这样),你就必须等待其他人的帮助。

相关问题