使用 SQL 游标显示数据库中的数据
Using SQL cursor for displaying data from database
我正在制作 C# Windows 表单应用程序,它已连接到数据库。
主题是:书店。
在其中一个应用程序的窗体中,有DataGridView,它显示了商店中每本书的信息。
在数据库中,一本书是唯一的,有它的 ISBN,在这种情况下,不同的书可以有相同的名字。
另外,书籍可以有很多作者。
意思是,当我进行显示所有书籍的查询时,它多次列出同一本书,以显示该书中的所有作者。
当然,我想要的是为一本书在一行中的一栏中列出所有作者。
有人告诉我这可以用游标来完成。
但是,我无法想象如何使用它们。
我不需要确切的代码,我只需要一些指南来解决这个问题。
此外,是否有更好的方法来执行此操作,然后使用游标?
如果您正在使用 Oracle-DB,您可以使用 LISTAGG - 函数如下:
SELECT listagg(a.author_name, ',') WITHIN GROUP (ORDER BY b.isin) names
FROM books b
join book_authors ba on ba.bookId = b.bookId
join authors a on a.authorId = ba.authorid
FOR XML
通常是将列放入逗号分隔列表的方法:
How to get column values in one comma separated value
显然不必用逗号分隔它们,您可以输入 CHAR(13) 或您需要的任何内容。
这是一个完成的代码示例,您可以如何执行此操作(也使用其他人已经建议的内容)。这就是您要找的吗?
-- declare variables
declare @ParamterCurrencyAmount numeric(26, 2),
@ParameterRollingVisitSum int
-- declare table variable
declare @Books table
(
ISBN int not null primary key,
BookName varchar(255) not null
)
-- declare table variable
declare @Authors table
(
AuthorID int primary key not null,
AuthorName varchar(255) not null
)
-- declare table variable
declare @BookAuthorRelations table
(
BookAuthorRelations int not null primary key,
ISBN int not null,
AuthorID int not null
)
-- insert sample data
insert into @Books
(
ISBN,
BookName
)
select 1000, 'Book A' union all
select 2000, 'Book B' union all
select 3000, 'Book C'
insert into @Authors
(
AuthorID,
AuthorName
)
select 1, 'Jack' union all
select 2, 'Peter' union all
select 3, 'Donald'
insert into @BookAuthorRelations
(
BookAuthorRelations,
ISBN,
AuthorID
)
select 1, 1000, 1 union all
select 2, 1000, 2 union all
select 3, 1000, 3 union all
select 4, 2000, 1 union all
select 5, 2000, 2 union all
select 6, 3000, 1
-- get books (with stuff)
select distinct Books.BookName,
stuff(
(
select distinct ', ' + Authors.AuthorName
from @Authors Authors,
@BookAuthorRelations BookAuthorRelations
where BookAuthorRelations.AuthorID = Authors.AuthorID
and Books.ISBN = BookAuthorRelations.ISBN
for xml path(''), type
).value('.', 'NVARCHAR(MAX)')
, 1, 2,'') data
from @Books Books
我正在制作 C# Windows 表单应用程序,它已连接到数据库。
主题是:书店。
在其中一个应用程序的窗体中,有DataGridView,它显示了商店中每本书的信息。
在数据库中,一本书是唯一的,有它的 ISBN,在这种情况下,不同的书可以有相同的名字。
另外,书籍可以有很多作者。
意思是,当我进行显示所有书籍的查询时,它多次列出同一本书,以显示该书中的所有作者。
当然,我想要的是为一本书在一行中的一栏中列出所有作者。
有人告诉我这可以用游标来完成。
但是,我无法想象如何使用它们。
我不需要确切的代码,我只需要一些指南来解决这个问题。
此外,是否有更好的方法来执行此操作,然后使用游标?
如果您正在使用 Oracle-DB,您可以使用 LISTAGG - 函数如下:
SELECT listagg(a.author_name, ',') WITHIN GROUP (ORDER BY b.isin) names
FROM books b
join book_authors ba on ba.bookId = b.bookId
join authors a on a.authorId = ba.authorid
FOR XML
通常是将列放入逗号分隔列表的方法:
How to get column values in one comma separated value
显然不必用逗号分隔它们,您可以输入 CHAR(13) 或您需要的任何内容。
这是一个完成的代码示例,您可以如何执行此操作(也使用其他人已经建议的内容)。这就是您要找的吗?
-- declare variables
declare @ParamterCurrencyAmount numeric(26, 2),
@ParameterRollingVisitSum int
-- declare table variable
declare @Books table
(
ISBN int not null primary key,
BookName varchar(255) not null
)
-- declare table variable
declare @Authors table
(
AuthorID int primary key not null,
AuthorName varchar(255) not null
)
-- declare table variable
declare @BookAuthorRelations table
(
BookAuthorRelations int not null primary key,
ISBN int not null,
AuthorID int not null
)
-- insert sample data
insert into @Books
(
ISBN,
BookName
)
select 1000, 'Book A' union all
select 2000, 'Book B' union all
select 3000, 'Book C'
insert into @Authors
(
AuthorID,
AuthorName
)
select 1, 'Jack' union all
select 2, 'Peter' union all
select 3, 'Donald'
insert into @BookAuthorRelations
(
BookAuthorRelations,
ISBN,
AuthorID
)
select 1, 1000, 1 union all
select 2, 1000, 2 union all
select 3, 1000, 3 union all
select 4, 2000, 1 union all
select 5, 2000, 2 union all
select 6, 3000, 1
-- get books (with stuff)
select distinct Books.BookName,
stuff(
(
select distinct ', ' + Authors.AuthorName
from @Authors Authors,
@BookAuthorRelations BookAuthorRelations
where BookAuthorRelations.AuthorID = Authors.AuthorID
and Books.ISBN = BookAuthorRelations.ISBN
for xml path(''), type
).value('.', 'NVARCHAR(MAX)')
, 1, 2,'') data
from @Books Books