从多个表中检索特定值
Retrieve particular value from multiple tables
我有 14 table 名不同类型的员工。我有一个连接到我的 SQL 服务器数据库的 C# 应用程序,当我在文本框中键入姓氏时,它会带回具有该姓氏的记录并将其显示在列表框中。
但是我只用了一个 table 就做到了。因此,如果我输入“Jones”,它将返回并显示 table.
中的 Jones
我想带回所有 14 table 中的所有琼斯。换句话说,当我键入一个姓氏时,我需要应用程序向我显示所有 14 个 table 中该姓氏的所有记录。
合理的方法是什么?如果我有一个 table 和所有员工在一起会容易得多,但我需要分开。基本上,当我单击搜索按钮时,我需要应用程序从具有给定名称的 14 个 table 中的任何一个中获取。
什么是 suitable 方法?
您应该重复您的代码 14 次以从所有这些表中收集值,或者您提交一次 SQL 对所有 14 个表的联合查询或在一个语句中提交 14 个查询 - 这取决于您的数据访问技术...
好的,要从所有 14 个 table 中获取结果,您可以使用 UNION ALL
运算符,因此您的 SQL 看起来像:
(SELECT first_name, last_name FROM table1 WHERE first_name='John')
UNION ALL
(SELECT first_name, last_name FROM table2 WHERE first_name='John')
...
(SELECT first_name, last_name FROM table14 WHERE first_name='John')
您需要在每个 select 中拥有相同数量的字段。然而,更好的方法是将所有名称(和任何其他共享数据)保存在一个 table 中,并使用 Key 连接所有具有不同数据集的 14 个 table。这样你就可以防止像上面这样的这么长的查询(并且可能是缓慢的查询)并且查询看起来更像这样:
SELECT first_name, last_name, user_type, user_id WHERE first_name='John'
然后您可以从相应的 table 中检索字段,因为字段 user_type
为您提供信息,其中 14 table 用于搜索其他数据和 user_id为您提供该用户的数据,因此第二个查询将如下所示:
SELECT job_position, worksheet, other_data FROM tableN WHERE user_id=...
在您的数据库中定义以下存储过程:
CREATE PROCEDURE GetAll_SP
(
@FirstName VARCHAR(50)
)
AS
BEGIN
(SELECT 1, first_name, last_name FROM UsersTable1 WHERE first_name = @FirstName)
UNION
(SELECT 2, first_name, last_name FROM UsersTable2 WHERE first_name = @FirstName)
UNION
(SELECT 3, first_name, last_name FROM UsersTable3 WHERE first_name = @FirstName)
-- ....
END
GO
或以下代替您不需要对您的用户位置进行任何控制:
CREATE PROCEDURE GetAll_SP
(
@FirstName VARCHAR(50)
)
AS
BEGIN
(SELECT first_name, last_name FROM UsersTable1 WHERE first_name = @FirstName)
UNION ALL
(SELECT first_name, last_name FROM UsersTable2 WHERE first_name = @FirstName)
UNION ALL
(SELECT first_name, last_name FROM UsersTable3 WHERE first_name = @FirstName)
-- ....
END
GO
然后,在您的代码中:
String firstName = "Jones";
using (SqlCommand cmd = new SqlCommand("GetAll_SP", m_Connection))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@FirstName", SqlDbType.VarChar).Value = firstName;
m_Connection.Open();
cmd.ExecuteNonQuery();
}
只需设置@SearchStr 即可搜索每个 table 中的每一列。
drop table #results
go
declare @SearchStr nvarchar(100)
set @SearchStr = 'Donna%' -- use wildcards
CREATE TABLE #Results (ColumnName nvarchar(370), ColumnValue nvarchar(3630))
SET NOCOUNT ON
DECLARE @TableName nvarchar(256), @ColumnName nvarchar(128), @SearchStr2 nvarchar(110)
SET @TableName = ''
SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%','''')
WHILE @TableName IS NOT NULL
BEGIN
SET @ColumnName = ''
SET @TableName =
(
SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName
AND OBJECTPROPERTY(
OBJECT_ID(
QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)
), 'IsMSShipped'
) = 0
)
WHILE (@TableName IS NOT NULL) AND (@ColumnName IS NOT NULL)
BEGIN
SET @ColumnName =
(
SELECT MIN(QUOTENAME(COLUMN_NAME))
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = PARSENAME(@TableName, 2)
AND TABLE_NAME = PARSENAME(@TableName, 1)
AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar', 'text')
AND QUOTENAME(COLUMN_NAME) > @ColumnName
)
print cast(@TableName as nvarchar(200)) + ' ' + @ColumnName
IF @ColumnName IS NOT NULL
BEGIN
INSERT INTO #Results
EXEC
(
--'SELECT ''' + @TableName + '.' + @ColumnName + ''', LEFT(' + @ColumnName + ', 3630)
--FROM ' + @TableName + ' (NOLOCK) ' +
--' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2
'SELECT ''' + @TableName + '.' + @ColumnName + ''', ' + @ColumnName + '
FROM ' + @TableName + ' (NOLOCK) ' +
' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2
)
END
END
END
SELECT ColumnName, ColumnValue FROM #Results
我有 14 table 名不同类型的员工。我有一个连接到我的 SQL 服务器数据库的 C# 应用程序,当我在文本框中键入姓氏时,它会带回具有该姓氏的记录并将其显示在列表框中。
但是我只用了一个 table 就做到了。因此,如果我输入“Jones”,它将返回并显示 table.
中的 Jones我想带回所有 14 table 中的所有琼斯。换句话说,当我键入一个姓氏时,我需要应用程序向我显示所有 14 个 table 中该姓氏的所有记录。
合理的方法是什么?如果我有一个 table 和所有员工在一起会容易得多,但我需要分开。基本上,当我单击搜索按钮时,我需要应用程序从具有给定名称的 14 个 table 中的任何一个中获取。
什么是 suitable 方法?
您应该重复您的代码 14 次以从所有这些表中收集值,或者您提交一次 SQL 对所有 14 个表的联合查询或在一个语句中提交 14 个查询 - 这取决于您的数据访问技术...
好的,要从所有 14 个 table 中获取结果,您可以使用 UNION ALL
运算符,因此您的 SQL 看起来像:
(SELECT first_name, last_name FROM table1 WHERE first_name='John')
UNION ALL
(SELECT first_name, last_name FROM table2 WHERE first_name='John')
...
(SELECT first_name, last_name FROM table14 WHERE first_name='John')
您需要在每个 select 中拥有相同数量的字段。然而,更好的方法是将所有名称(和任何其他共享数据)保存在一个 table 中,并使用 Key 连接所有具有不同数据集的 14 个 table。这样你就可以防止像上面这样的这么长的查询(并且可能是缓慢的查询)并且查询看起来更像这样:
SELECT first_name, last_name, user_type, user_id WHERE first_name='John'
然后您可以从相应的 table 中检索字段,因为字段 user_type
为您提供信息,其中 14 table 用于搜索其他数据和 user_id为您提供该用户的数据,因此第二个查询将如下所示:
SELECT job_position, worksheet, other_data FROM tableN WHERE user_id=...
在您的数据库中定义以下存储过程:
CREATE PROCEDURE GetAll_SP
(
@FirstName VARCHAR(50)
)
AS
BEGIN
(SELECT 1, first_name, last_name FROM UsersTable1 WHERE first_name = @FirstName)
UNION
(SELECT 2, first_name, last_name FROM UsersTable2 WHERE first_name = @FirstName)
UNION
(SELECT 3, first_name, last_name FROM UsersTable3 WHERE first_name = @FirstName)
-- ....
END
GO
或以下代替您不需要对您的用户位置进行任何控制:
CREATE PROCEDURE GetAll_SP
(
@FirstName VARCHAR(50)
)
AS
BEGIN
(SELECT first_name, last_name FROM UsersTable1 WHERE first_name = @FirstName)
UNION ALL
(SELECT first_name, last_name FROM UsersTable2 WHERE first_name = @FirstName)
UNION ALL
(SELECT first_name, last_name FROM UsersTable3 WHERE first_name = @FirstName)
-- ....
END
GO
然后,在您的代码中:
String firstName = "Jones";
using (SqlCommand cmd = new SqlCommand("GetAll_SP", m_Connection))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@FirstName", SqlDbType.VarChar).Value = firstName;
m_Connection.Open();
cmd.ExecuteNonQuery();
}
只需设置@SearchStr 即可搜索每个 table 中的每一列。
drop table #results
go
declare @SearchStr nvarchar(100)
set @SearchStr = 'Donna%' -- use wildcards
CREATE TABLE #Results (ColumnName nvarchar(370), ColumnValue nvarchar(3630))
SET NOCOUNT ON
DECLARE @TableName nvarchar(256), @ColumnName nvarchar(128), @SearchStr2 nvarchar(110)
SET @TableName = ''
SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%','''')
WHILE @TableName IS NOT NULL
BEGIN
SET @ColumnName = ''
SET @TableName =
(
SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName
AND OBJECTPROPERTY(
OBJECT_ID(
QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)
), 'IsMSShipped'
) = 0
)
WHILE (@TableName IS NOT NULL) AND (@ColumnName IS NOT NULL)
BEGIN
SET @ColumnName =
(
SELECT MIN(QUOTENAME(COLUMN_NAME))
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = PARSENAME(@TableName, 2)
AND TABLE_NAME = PARSENAME(@TableName, 1)
AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar', 'text')
AND QUOTENAME(COLUMN_NAME) > @ColumnName
)
print cast(@TableName as nvarchar(200)) + ' ' + @ColumnName
IF @ColumnName IS NOT NULL
BEGIN
INSERT INTO #Results
EXEC
(
--'SELECT ''' + @TableName + '.' + @ColumnName + ''', LEFT(' + @ColumnName + ', 3630)
--FROM ' + @TableName + ' (NOLOCK) ' +
--' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2
'SELECT ''' + @TableName + '.' + @ColumnName + ''', ' + @ColumnName + '
FROM ' + @TableName + ' (NOLOCK) ' +
' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2
)
END
END
END
SELECT ColumnName, ColumnValue FROM #Results