Comments (20)
@SheltonZhu https://github.com/godoes/gorm-oracle/releases/tag/v1.5.19 已修复并发布,有空可以试一下。
from gorm-oracle.
还有就是 left join order by 的时候,生成的order by 字段名没有带表名导致执行失败,但是我不确定是不是驱动造成的,mysql是正常的
这个问题可以再详细描述一下吗?比如添加一些示例代码以及 MySQL 和 Oracle 的对比 SQL。
是我看错了, 是count语句生成的不一样: mysql 生成 select count(*) from xxx
但是 oracle 生成的 select count(*) from xxx by id
, 我再看看, 有问题我再另提issue。
from gorm-oracle.
注释到这几句就正常了, 没看明白这几行是用于什么场景的
用来在分页查询时如果没有指定排序方式的话使用主键作为默认排序方式。
在 Oracle 数据库中,如果你使用 OFFSET
进行分页查询,通常建议在查询中显式指定排序方式,尤其是在使用 OFFSET
和 FETCH NEXT
进行分页时。
原因是,OFFSET
和 FETCH NEXT
语法是和排序相关的,如果没有明确指定排序方式,查询结果的顺序可能是不确定的。在分页查询中,不确定的顺序可能导致在不同页之间的重复或遗漏的数据。
示例:
SELECT *
FROM your_table
ORDER BY your_column
OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;
在上面的示例中,ORDER BY your_column
明确指定了排序方式,确保在进行分页查询时结果是可预测的。如果你省略了 ORDER BY
子句,查询结果的顺序可能会随数据库的实现而变化,可能不符合你的预期。
因此,为了确保分页查询的结果是有序的,建议在使用 OFFSET
和 FETCH NEXT
进行分页时,总是显式指定排序方式。
from gorm-oracle.
请问你用的哪个版本?我用最新版 v1.5.18
测试 int32
类型的主键是返回了值的:
from gorm-oracle.
请问你用的哪个版本?我用最新版
v1.5.18
测试int32
类型的主键是返回了值的:
github.com/godoes/gorm-oracle v1.5.18
type DocCompareUser struct {
ID int32 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` // 自增id
Name *string `gorm:"column:name" json:"name"` // 用户名称
Account *string `gorm:"column:account" json:"account"` // 账户名称
Password *string `gorm:"column:password" json:"password"` // 用户密码md5
Status *int32 `gorm:"column:status" json:"status"` // 用户状态,1 正常 -1 删除 2 停用
Ctm *time.Time `gorm:"column:ctm" json:"ctm"` // 创建时间
Utm *time.Time `gorm:"column:utm" json:"utm"` // 更新时间
Type *int32 `gorm:"column:type" json:"type"` // 用户类型
AdminID int32 `gorm:"column:admin_id;not null" json:"admin_id"` // 暂无特别含义,可以忽略
Note string `gorm:"column:note;not null" json:"note"` // 账号备注
ExpireTime time.Time `gorm:"column:expire_time;not null;default:2121-01-01 00:00:00" json:"expire_time"` // 过期时间
Deleted int32 `gorm:"column:deleted;not null;default:-1" json:"deleted"` // 不为-1表示已经删除
SourceID int32 `gorm:"column:source_id;not null;default:-1" json:"source_id"` // 来源类型, -1 代表原生用户, 其他代表其他sso登录方式的配置id
SsoUserUniqueID string `gorm:"column:sso_user_unique_id;not null" json:"sso_user_unique_id"` // 其他方式创建的用户的唯一标识
}
我是通过 gorm/gen 去使用的
from gorm-oracle.
好的,我明天再试一下
from gorm-oracle.
感谢🙏
还有就是 left join order by 的时候,生成的order by 字段名没有带表名导致执行失败,但是我不确定是不是驱动造成的,mysql是正常的
oracle 版本是 19c
from gorm-oracle.
请问你用的哪个版本?我用最新版
v1.5.18
测试int32
类型的主键是返回了值的:
还有一个问题想请教一下,定义struct的时候,gorm 的tag是小写下划线,oracle创建数据库的时候是大写下划线,go-ora驱动的 rows.Columns方法返回的是全大写,我看gorm 绑定字段的时候是去找tag也就是dbname和keyname,导致绑定不上数据,但是你给的这个似乎没问题?
from gorm-oracle.
还有一个问题想请教一下,定义struct的时候,gorm 的tag是小写下划线,oracle创建数据库的时候是大写下划线,go-ora驱动的 rows.Columns方法返回的是全大写,我看gorm 绑定字段的时候是去找tag也就是dbname和keyname,导致绑定不上数据,但是你给的这个似乎没问题?
可以参考这个问题的回答:
from gorm-oracle.
请问你用的哪个版本?我用最新版
v1.5.18
测试int32
类型的主键是返回了值的:还有一个问题想请教一下,定义struct的时候,gorm 的tag是小写下划线,oracle创建数据库的时候是大写下划线,go-ora驱动的 rows.Columns方法返回的是全大写,我看gorm 绑定字段的时候是去找tag也就是dbname和keyname,导致绑定不上数据,但是你给的这个似乎没问题?
可以参考这个问题的回答:
我使用的配置如下, sql是可以执行的, 结果也能拿得到, 是在rows 绑定到 struct的过程中,没有绑定上, 通过调试发现 在 gorm/scan.go
的 func Scan(rows Rows, db *DB, mode ScanMode)
中会去获取go-ora的列名 columns, _ = rows.Columns()
拿到的都是全大写, 然后去 sch.LookUpField(column)
,寻找,但是只在FieldsByDBName
和FieldsByName
中找, FieldsByDBName
中是gorm 的columu, tag,全小写, 所以找不到,最后没有把数据绑定上.
options := map[string]string{
"CONNECTION TIMEOUT": "90",
"LANGUAGE": "SIMPLIFIED CHINESE",
"TERRITORY": "CHINA",
"SSL": "false",
"lob fetch": "post",
}
// oracle://user:[email protected]:1521/database
url := oracle.BuildUrl(opts.Host, opts.Port, opts.Database, opts.Username, opts.Password, options)
return oracle.New(oracle.Config{
DSN: url,
IgnoreCase: false, // query conditions are not case-sensitive
NamingCaseSensitive: false, // whether naming is case-sensitive
}), nil
var (
columns, _ = rows.Columns()
values = make([]interface{}, len(columns))
initialized = mode&ScanInitialized != 0
update = mode&ScanUpdate != 0
onConflictDonothing = mode&ScanOnConflictDoNothing != 0
)
func (schema Schema) LookUpField(name string) *Field {
if field, ok := schema.FieldsByDBName[name]; ok {
return field
}
if field, ok := schema.FieldsByName[name]; ok {
return field
}
return nil
}
from gorm-oracle.
我使用的配置如下, sql是可以执行的, 结果也能拿得到, 是在rows 绑定到 struct的过程中,没有绑定上, 通过调试发现 在
gorm/scan.go
的func Scan(rows Rows, db *DB, mode ScanMode)
中会去获取go-ora的列名columns, _ = rows.Columns()
拿到的都是全大写, 然后去sch.LookUpField(column)
,寻找,但是只在FieldsByDBName
和FieldsByName
中找,FieldsByDBName
中是gorm 的columu, tag,全小写, 所以找不到,最后没有把数据绑定上.
启用 NamingCaseSensitive
后会使用双引号包裹字段名,自动迁移表结构时创建的字段才会是小写的,否则字段名没有加双引号 Oracle 数据库默认创建大写字段,就不能跟 tag 指定的小写字段匹配上。所以要么 tag 改成大写,要么启用 NamingCaseSensitive
。
from gorm-oracle.
否则字段名没
好的,感谢大佬解答
我这边因为某些原因不能使用自动迁移表结构功能, 创建的都是大写字段,目前是写了了插件在FieldsByDBName
中添加了大写的key来解决的
from gorm-oracle.
感谢大佬解答
额,互相交流,没必要搞这些名词。这个库本身还不够完善,有人反馈问题我也很感谢。
我这边因为某些原因不能使用自动迁移表结构功能, 创建的都是大写字段
如果是使用 SQL 脚本创建表结构,想要小写表名和字段名可以手动加双引号,比如:
创建小写表名和字段名
-- drop table SYSTEM."test_user";
create table SYSTEM."test_user" (
"id" NUMBER generated as identity primary key,
"name" VARCHAR2(50),
"account" VARCHAR2(50),
"password" VARCHAR2(512),
"email" VARCHAR2(128),
"phone_number" VARCHAR2(15),
"sex" CHAR,
"birthday" TIMESTAMP(6) WITH TIME ZONE,
"user_type" NUMBER,
"enabled" NUMBER(1),
"remark" VARCHAR2(1024),
"uid" VARCHAR2(50),
"add_new_column" VARCHAR2(100),
"comment_single_quote" VARCHAR2(1024)
);
comment on table SYSTEM."test_user" is '用户信息表';
comment on column SYSTEM."test_user"."id" is '自增 ID';
comment on column SYSTEM."test_user"."name" is '用户姓名';
comment on column SYSTEM."test_user"."account" is '登录账号';
comment on column SYSTEM."test_user"."password" is '登录密码(密文)';
comment on column SYSTEM."test_user"."email" is '邮箱地址';
comment on column SYSTEM."test_user"."phone_number" is 'E.164';
comment on column SYSTEM."test_user"."sex" is '性别';
comment on column SYSTEM."test_user"."birthday" is '生日';
comment on column SYSTEM."test_user"."user_type" is '用户类型';
comment on column SYSTEM."test_user"."enabled" is '是否可用';
comment on column SYSTEM."test_user"."remark" is '备注信息';
comment on column SYSTEM."test_user"."uid" is '用户身份标识';
comment on column SYSTEM."test_user"."add_new_column" is '测试添加新字段';
comment on column SYSTEM."test_user"."comment_single_quote" is '注释中存在单引号''['']''';
from gorm-oracle.
是的,现在在想办法批量加引号😂
from gorm-oracle.
我用 Oracle19c 和你给的结构体测试也返回了 ID,确定你数据库里的 ID 字段是自增的吗?DocCompareUser
结构体有没有 AfterFind
类的钩子方法或其他处理?
from gorm-oracle.
我用 Oracle19c 和你给的结构体测试也返回了 ID,确定你数据库里的 ID 字段是自增的吗?
DocCompareUser
结构体有没有AfterFind
类的钩子方法或其他处理?使用 Oracle19c 和 DocCompareUser 结构体测试结果
CREATE TABLE "doc_compare_user" (
"id" NUMBER(10, 0) GENERATED BY DEFAULT ON NULL AS IDENTITY START WITH 143 INCREMENT BY 1 MINVALUE 1 NOMAXVALUE,
"name" VARCHAR2(255 CHAR),
"account" VARCHAR2(255 CHAR),
"password" VARCHAR2(255 CHAR),
"status" NUMBER(10, 0),
"ctm" TIMESTAMP(0),
"utm" TIMESTAMP(0),
"type" NUMBER(10, 0),
"admin_id" NUMBER(10, 0) NOT NULL,
"note" VARCHAR2(10 CHAR),
"expire_time" TIMESTAMP(0) NOT NULL,
"deleted" NUMBER(10, 0) NOT NULL,
"source_id" NUMBER(3, 0) NOT NULL,
"sso_user_unique_id" VARCHAR2(255 CHAR) NOT NULL
);
COMMENT ON COLUMN "doc_compare_user"."id" IS '自增id';
创建语句是这么写的(这个是替换引号后的, 响应的insert语句也要加上"")
没有写过 AfterFind
钩子, gorm/gen 生成的代码里也没有看到
如果你那边没有问题, 那大概率是gorm/gen
这个库做了什么吧...把 insertTo.Kind() 的类型变成了 指针
case reflect.Pointer:
_, isZero := db.Statement.Schema.PrioritizedPrimaryField.ValueOf(db.Statement.Context, insertTo)
if isZero {
_ = db.AddError(db.Statement.Schema.PrioritizedPrimaryField.Set(db.Statement.Context, insertTo, v.Dest))
}
我加了这句就可以赋值id了
from gorm-oracle.
type docCompareUserDo struct{ gen.DO }
type IDocCompareUserDo interface {
gen.SubQuery
Debug() IDocCompareUserDo
WithContext(ctx context.Context) IDocCompareUserDo
WithResult(fc func(tx gen.Dao)) gen.ResultInfo
ReplaceDB(db *gorm.DB)
ReadDB() IDocCompareUserDo
WriteDB() IDocCompareUserDo
As(alias string) gen.Dao
Session(config *gorm.Session) IDocCompareUserDo
Columns(cols ...field.Expr) gen.Columns
Clauses(conds ...clause.Expression) IDocCompareUserDo
Not(conds ...gen.Condition) IDocCompareUserDo
Or(conds ...gen.Condition) IDocCompareUserDo
Select(conds ...field.Expr) IDocCompareUserDo
Where(conds ...gen.Condition) IDocCompareUserDo
Order(conds ...field.Expr) IDocCompareUserDo
Distinct(cols ...field.Expr) IDocCompareUserDo
Omit(cols ...field.Expr) IDocCompareUserDo
Join(table schema.Tabler, on ...field.Expr) IDocCompareUserDo
LeftJoin(table schema.Tabler, on ...field.Expr) IDocCompareUserDo
RightJoin(table schema.Tabler, on ...field.Expr) IDocCompareUserDo
Group(cols ...field.Expr) IDocCompareUserDo
Having(conds ...gen.Condition) IDocCompareUserDo
Limit(limit int) IDocCompareUserDo
Offset(offset int) IDocCompareUserDo
Count() (count int64, err error)
Scopes(funcs ...func(gen.Dao) gen.Dao) IDocCompareUserDo
Unscoped() IDocCompareUserDo
Create(values ...*model.DocCompareUser) error
CreateInBatches(values []*model.DocCompareUser, batchSize int) error
Save(values ...*model.DocCompareUser) error
First() (*model.DocCompareUser, error)
Take() (*model.DocCompareUser, error)
Last() (*model.DocCompareUser, error)
Find() ([]*model.DocCompareUser, error)
FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.DocCompareUser, err error)
FindInBatches(result *[]*model.DocCompareUser, batchSize int, fc func(tx gen.Dao, batch int) error) error
Pluck(column field.Expr, dest interface{}) error
Delete(...*model.DocCompareUser) (info gen.ResultInfo, err error)
Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
Updates(value interface{}) (info gen.ResultInfo, err error)
UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
UpdateColumns(value interface{}) (info gen.ResultInfo, err error)
UpdateFrom(q gen.SubQuery) gen.Dao
Attrs(attrs ...field.AssignExpr) IDocCompareUserDo
Assign(attrs ...field.AssignExpr) IDocCompareUserDo
Joins(fields ...field.RelationField) IDocCompareUserDo
Preload(fields ...field.RelationField) IDocCompareUserDo
FirstOrInit() (*model.DocCompareUser, error)
FirstOrCreate() (*model.DocCompareUser, error)
FindByPage(offset int, limit int) (result []*model.DocCompareUser, count int64, err error)
ScanByPage(result interface{}, offset int, limit int) (count int64, err error)
Scan(result interface{}) (err error)
Returning(value interface{}, columns ...string) IDocCompareUserDo
UnderlyingDB() *gorm.DB
schema.Tabler
}
from gorm-oracle.
还有就是 left join order by 的时候,生成的order by 字段名没有带表名导致执行失败,但是我不确定是不是驱动造成的,mysql是正常的
这个问题可以再详细描述一下吗?比如添加一些示例代码以及 MySQL 和 Oracle 的对比 SQL。
from gorm-oracle.
func (d Dialector) RewriteLimit(c clause.Clause, builder clause.Builder) {
if limit, ok := c.Expression.(clause.Limit); ok {
// if stmt, ok := builder.(*gorm.Statement); ok {
// if _, ok := stmt.Clauses["ORDER BY"]; !ok {
// s := stmt.Schema
// _, _ = builder.WriteString("ORDER BY ")
// if s != nil && s.PrioritizedPrimaryField != nil {
// builder.WriteQuoted(s.PrioritizedPrimaryField.DBName)
// _ = builder.WriteByte(' ')
// } else {
// _, _ = builder.WriteString("(SELECT NULL FROM ")
// _, _ = builder.WriteString(d.DummyTableName())
// _, _ = builder.WriteString(")")
// }
// }
// }
if offset := limit.Offset; offset > 0 {
_, _ = builder.WriteString(" OFFSET ")
_, _ = builder.WriteString(strconv.Itoa(offset))
_, _ = builder.WriteString(" ROWS")
}
if limit := limit.Limit; limit != nil && *limit >= 0 {
_, _ = builder.WriteString(" FETCH NEXT ")
_, _ = builder.WriteString(strconv.Itoa(*limit))
_, _ = builder.WriteString(" ROWS ONLY")
}
}
}
注释到这几句就正常了, 没看明白这几行是用于什么场景的
from gorm-oracle.
注释到这几句就正常了, 没看明白这几行是用于什么场景的
用来在分页查询时如果没有指定排序方式的话使用主键作为默认排序方式。
在 Oracle 数据库中,如果你使用
OFFSET
进行分页查询,通常建议在查询中显式指定排序方式,尤其是在使用OFFSET
和FETCH NEXT
进行分页时。原因是,
OFFSET
和FETCH NEXT
语法是和排序相关的,如果没有明确指定排序方式,查询结果的顺序可能是不确定的。在分页查询中,不确定的顺序可能导致在不同页之间的重复或遗漏的数据。示例:
SELECT * FROM your_table ORDER BY your_column OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;在上面的示例中,
ORDER BY your_column
明确指定了排序方式,确保在进行分页查询时结果是可预测的。如果你省略了ORDER BY
子句,查询结果的顺序可能会随数据库的实现而变化,可能不符合你的预期。因此,为了确保分页查询的结果是有序的,建议在使用
OFFSET
和FETCH NEXT
进行分页时,总是显式指定排序方式。
明白了这个的作用了,但是为什么count函数会进到这里面来,count应该不需要排序, gorm/gen 的count,应该用的也是gorm的count函数。而且我有leftjoin,生成的语句没有 tablename前缀,所以不知道是哪张表的id
from gorm-oracle.
Related Issues (12)
- 列名大小写问题 HOT 1
- CLOB 字段数据过长时报 ORA-01461: 仅能绑定要插入 LONG 列的 LONG 值
- Oracle11 以上版本数据库查询数据使用 Limit(-1) 时也会设置默认排序字段 HOT 1
- 能用在生产环境嘛? HOT 2
- 分页问题 HOT 1
- Using `schema.Namer` to support customize naming strategy
- Oracle stored procedure OUT Variables HOT 1
- when a entity has a `[]byte` field, call `AutoMigrate()` throw ` ORA-22859: invalid modification of columns` HOT 1
- 结构体中如果存在保留字段,默认会多加一对双引号,导致数据库自动创建表失败。 HOT 1
- 在gorm的自定义类型`JSONMap` 时,在已生成表的情况下,再次运行数据库迁移报`ORA-22859: 无效的列修改` HOT 1
- 插入数据时缺少 `[]byte`到 `BLOB` 类型的转换,插入数据不成功 HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from gorm-oracle.