SQL选择可能拥有特定值
因此,您希望对您的数据库执行类似谷歌的免费文本搜索。这可以做,但表现将是Teh Suck! Google的速度很快,因为它的索引有索引,重复数据存储,并且通常会针对这种搜索进行优化。
无论如何,这里是使用动态SQL和Oracle数据字典的概念证明。请注意,我将列限制为要搜索的数据类型,即字符串。
SQL> set serveroutput on size unlimited
SQL> declare
2 dummy varchar2(1);
3 begin
4 for r in (select table_name, column_name from user_tab_cols
5 where data_type in ('VARCHAR2', 'CHAR', 'CLOB'))
6 loop
7 begin
8 execute immediate 'select null from '||r.table_name
9 ||' where '||r.column_name||' like ''%&search_value%'' '
10 ||' and rownum = 1'
11 into dummy;
12 dbms_output.put_line('Found it in >>>'
13 ||r.table_name||'.'||r.column_name);
14 exception
15 when others then
16 -- bad practice ahoy!
17 null;
18 end;
19 end loop;
20 end;
21/
Enter value for search_value: MAISIE
old 9: ||' where '||r.column_name||' like ''%&search_value%'' '
new 9: ||' where '||r.column_name||' like ''%MAISIE%'' '
Found it in >>>T23.NAME
PL/SQL procedure successfully completed.
SQL>
更健壮的实现可能需要处理的情况下,整个单词等,如果你在10g或更高版本,然后正则表达式可能是有用的,但正则表达式相结合,动态SQL是一个,呃,有趣前景。
我再说一次,表现会是Teh Suck!在一个大型数据集上。调整几乎是不可能的,因为我们无法对每一列进行索引,当然也不支持LIKE或类似的模糊匹配。另一种方法是使用XQuery生成数据的XML表示,然后使用文本对其进行索引。维护这样一个存储库将会是开销,但是如果您需要定期使用这种功能,那么这种努力将是一个合理的投资,尤其是在生产环境中。
SELECT * FROM table WHERE column='xxx';
但如果你有其中可以包含该值多少列,您需要使用OR:
SELECT * FROM table WHERE column1='xxx' or column2='xxx' or column3='xxx';
select * from table_name where(Table_Attribute ='XXX');
这会告诉你这得到期望的结果与属性XXX
sagar,你是什么意思作为TABLE_ATTRIBUTE? – sergionni 2010-07-20 08:43:18
那你列的像 student_id数据 – 2010-07-20 08:45:57
或类似Student_Name =“XXX” – 2010-07-20 08:46:33
运行的所有记录,使用SRY坏命名。
declare @_var nvarchar(1000)
declare @var1 nvarchar(1000)
declare @var2 nvarchar(1000)
declare _cur cursor
for select
case Column_name
when '' then ''
else Column_name+'=''asd'' OR '
end
from information_schema.columns
where table_name='M_Patient'
and
data_type ='nvarchar'
open _cur
fetch _cur into @_var
while(@@fetch_status=0)
begin
set @var2=isnull(@var2,'')[email protected]_var
fetch _cur into @_var
end
close _cur
deallocate _cur
set @var1='select * from M_Patient where '+ substring(@var2, 0,len(@var2)-2)
execute (@var1)
我通常使用这个脚本,如果我需要在数据库中搜索一个值并且我不知道表和/或列。只需设置@SearcStr参数并按下播放即可。也许它可以帮助你。
DROP TABLE #Results
DECLARE @SearchStr nvarchar(100)
SET @SearchStr = ''
CREATE TABLE
#Results(ColumnName nvarchar(370), ColumnValue nvarchar(3630))
SET NOCOUNT ON
DECLARE @TableName nvarchar(256)
DECLARE @ColumnName nvarchar(128)
DECLARE @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')
AND QUOTENAME(COLUMN_NAME) > @ColumnName
)
IF @ColumnName IS NOT NULL
BEGIN
INSERT INTO #Results
EXEC
(
'SELECT ''' + @TableName + '.' + @ColumnName + ''', LEFT(' + @ColumnName + ', 3630)
FROM ' + @TableName + ' (NOLOCK) ' +
' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2
)
END
END
END
SELECT
ColumnName
,ColumnValue
FROM
#Results
如果您需要这样做一次或两次,那么APC的答案是好的。如果这在某种程度上(不寒而栗)是持续需求的一部分,那么我认为您可以做的最好的事情是在感兴趣的表或表上创建一个Oracle计算字段并在其上进行搜索。使用您确定不会显示在实际文本值中的分隔符,例如:
alter table mytable add search_column
as (mycolumn1||'^'||mycolumn2||'^'||mycolumn3);
现在您的查询就会变成这样的:
select <whatever transformation you want to see here>
from mytable where search_column like '%^xxx^%'
只是一个评论(您可能刚才听到的是科德在他的坟墓纺那声音):尽量避免这种情况。 SQL不允许直接使用它(没有特定的语法),即使有动态SQL的解决方法,健壮的数据库应用程序应该保持简单和愚蠢,而动态SQL隐藏了复杂性,这通常意味着迟早会出现问题(在意外功能条款,性能问题和/或安全问题)。 – Unreason 2010-07-20 09:19:07
您想要在数据库管理系统中执行最基本的任务之一(即应用搜索条件返回结果集),但是您的模式阻止您这样做。我会断定你已经误解了架构或架构是致命的缺陷。 – onedaywhen 2010-07-20 10:21:58
谢谢你的答案,我只是想补充说,这样的选择表达式我不会在应用程序中使用,它需要我定义以下映射:记录从文件(输入ASCII) - >从现有DB – sergionni 2010-07-20 12:50:14