所有的我已经看到了使用实施例sql.Row
,获得的返回值,从查询由 位置 :sql.Rows.scan()
需要正确地正确类型的变量
定位 在scan()
对应于相应的列,来检索每个列的值的参数返回,如在下面的例子:
基于GoDocs的示例(带有小型mod):
rows, err := db.Query("SELECT name,age FROM users WHERE age>=50")
if err != nil {
log.Fatal(err)
}
for rows.Next() {
var name string
var age int
if err := rows.Scan(&name,&age); err != nil {
log.Fatal(err)
}
fmt.Printf("%s is %d\n", name, age)
}
if err := rows.Err(); err != nil {
log.Fatal(err)
}
&name
并且&age
必须正确放置Rows.Scan()的位置(0和1列),以检索具有正确类型的正确值。
在生产系统的多年开发中,我一直在避免这种做法,因为这种做法不够可靠:如果数据库的布局基于列位置,则更改列布局会很容易破坏您的代码。
使用 列名 检索值要更健壮-
这样可以使您免受对数据库的更改的影响,这些更改添加或删除了会损坏基于位置的代码的列。例如,在Delphi和C#中,所有的数据集,包括返回从查询,支持值的列FieldByName('age').asInteger
或fields['age'].value,
等
有什么办法可以在Go中做到这一点?如果不是这样,这将是Go数据库支持中的一个很大缺点,并且会令人严重失望-完全不安全,如上所述。
编辑:
另外 (也许这是一个新问题) :我所看到的示例似乎要求您检索查询返回的所有列,否则列的位置将倾斜。
假设在锁定的数据库中存在无法修改或添加的实用程序查询,并且它检索了几列,但是对于当前任务,我只需要其中一列。基于当前sql.Rows.Scan()
模型,即使我不需要它们,我也必须从应用程序代码中的查询中检索所有值,而如果我可以查询"columnByName"
不必要的值,则可以将我的应用程序代码带入我需要的数据。有任何解决方法吗?
是的,可以这样做,而不必手动匹配列位置。您可以使用一些第三方库来执行此操作,例如sqlx或gorp。我建议坚持使用其中之一,而不要自己动手。
命名匹配确实会有轻微的损失。命名匹配与自己匹配列位置没有什么不同。它只是在运行时为您完成这项工作-可能会在每次查询执行时执行。在任何其他语言中都是如此。
为什么在运行时?查询被写为字符串。必须对其进行分析以确定位置。
如果要创建自己的库,该如何自己做呢?
将切片的指针传递[]interface{}
给Rows.Scan以获取值。
reflect.Value和Value.Addr获得指向目标值的指针。
Value
如果要映射到结构字段,则使用Value.FieldByName获取结构字段的。
好的,让我们看看它是如何工作的。
type Person struct {
Id int
Name string
}
rows, err := db.Query("SELECT id, name FROM person;")
if err != nil {
// handle err
log.Fatal(err)
}
columnNames, err := rows.Columns() // []string{"id", "name"}
if err != nil {
// handle err
log.Fatal(err)
}
people = make([]Person, 0, 2)
for rows.Next() {
person := Person{}
// person == Person{0, ""}
pointers := make([]interface{}, len(columnNames))
// pointers == `[]interface{}{nil, nil}`
structVal := reflect.ValueOf(person)
for i, colName := range columnNames {
fieldVal := structVal.FieldByName(strings.Title(colName))
if !fieldVal.IsValid() {
log.Fatal("field not valid")
}
pointers[i] = fieldVal.Addr().Interface()
}
// pointers == `[]interface{}{&int, &string}`
err := rows.Scan(pointers...)
if err != nil {
// handle err
log.Fatal(err)
}
// person == Person{1, "John Doe"}
people = append(people, person)
}
问题内容: 我正在编写一些工具,当对它应用任何查询时,该工具必须检索检索到的数据集的列名。 如果您熟悉phpMyAdmin,您将意识到SQL窗格可以执行查询并显示结果以及列名。我想知道查询会有多困难,它总是产生列名,而幕后的编程实际上是什么?就像它会分析查询,然后从查询中查找表名称,然后首先使用查询检索列名称,然后再检索数据吗? 有什么更好的办法吗? 已更新 对不起,不完整的信息,我想我必须说我在
问题内容: 我有一个看起来像这样的表: 我想获得一个二维表,该表为我提供每个站点月份的“ Val”,例如: 但是要注意的是,我不知道“站点”中所有可能的值。如果出现一个新站点,我想在结果表中自动获得一个新列。 我看到的所有可以做到这一点的代码示例都要求我在查询文本中对“ Microsoft and Google”进行硬编码。 我看到了一个没有,但是基本上是通过列出站点并在其中生成带有这些列名称的查
我知道有可能通过名字得到一个类,使用 是否可以通过名称检索注释?我尝试了这个: 然后将c转换为
问题内容: 如果我有: 如何使用T-SQL获得元素名称“名称”和“内容”的列表? 到目前为止,我得到的最好成绩是: 但是,当然,我无法解决这个问题。 问题答案: 实际上,对不起,我得到的最好的是: 猜猜我回答了我自己的问题…
问题内容: 自从我上次使用1.4.X版本以来,我一直在尝试更新有关Java的知识…我正在尝试使用1.6.0,尤其是Java Persistence API(2.0)。 我设法创建了一个实体类。因为我能够存储和检索数据,所以它正在工作。 但是我无所事事,当我决定用表的列名填充JList时并没有成功… 这是一个简单的类,看起来像: 有没有办法检索列名? 我找到了这个帖子。似乎是一个有效的解决方案,
是否有任何方法可以在数据框中按索引(即整数)选择行,按列名选择列? 我尝试使用loc,但它返回一个错误,我知道iloc只适用于索引。 这是数据帧df的第一行。我愿意选择第一行,名为“Volume”的列,并尝试使用df.loc[0,'Volume']