SQL选择可能拥有特定值

问题描述:

如何选择所有记录的所有记录,可能含有被称为特定值,没有SQL表达式指特定列SQL选择可能拥有特定值

举例来说,我知道,有些未知列包含值“XXX”,并有表中的列和记录。

谢谢。

+2

只是一个评论(您可能刚才听到的是科德在他的坟墓纺那声音):尽量避免这种情况。 SQL不允许直接使用它(没有特定的语法),即使有动态SQL的解决方法,健壮的数据库应用程序应该保持简单和愚蠢,而动态SQL隐藏了复杂性,这通常意味着迟早会出现问题(在意外功能条款,性能问题和/或安全问题)。 – Unreason 2010-07-20 09:19:07

+2

您想要在数据库管理系统中执行最基本的任务之一(即应用搜索条件返回结果集),但是您的模式阻止您这样做。我会断定你已经误解了架构或架构是致命的缺陷。 – onedaywhen 2010-07-20 10:21:58

+0

谢谢你的答案,我只是想补充说,这样的选择表达式我不会在应用程序中使用,它需要我定义以下映射:记录从文件(输入ASCII) - >从现有DB – sergionni 2010-07-20 12:50:14

因此,您希望对您的数据库执行类似谷歌的免费文本搜索。这可以做,但表现将是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'; 
+0

列尝试,得到: ORA-00936:缺少表达式 00936. 00000 - “缺少表达式” – sergionni 2010-07-20 08:33:28

+0

我提到了选择查询而没有提及特定列,是否可以在SQL中使用。也许存在一些特定的关键字。 – sergionni 2010-07-20 08:35:45

+2

问题不在于指定列号 – 2010-07-20 08:51:32

如果不能明确写入了所有可能的列时,应使用模式产生dynamic SQL querymetadata

select * from table_name where(Table_Attribute ='XXX');

这会告诉你这得到期望的结果与属性XXX

+0

sagar,你是什么意思作为TABLE_ATTRIBUTE? – sergionni 2010-07-20 08:43:18

+0

那你列的像 student_id数据 – 2010-07-20 08:45:57

+0

或类似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) 
+0

什么是Column_name? – sergionni 2010-07-20 08:50:31

+0

@sergionni:它是存储在sql server中的元数据。在sql server查询分析器中写入一个查询,如下所示:** select * from information_schema.columns **,您将开始得到你需要做什么来查询结果 – 2010-07-20 08:53:53

+0

有错误: ORA-00942:表或视图不存在 – sergionni 2010-07-20 09:00:22

我通常使用这个脚本,如果我需要在数据库中搜索一个值并且我不知道表和/或列。只需设置@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 
+0

问题标记为[Oracle],不幸的是您的查询不使用Oracle数据字典或Oracle语法。 – APC 2010-07-20 12:11:12

+0

我似乎已经失去了我的眼睛 - 谢谢:) – ramad 2010-07-20 12:20:36

如果您需要这样做一次或两次,那么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^%' 

+0

这是一个聪明的解决方案;我希望我能想到它。 (你会的,奥斯卡,你会的)。有几个问题。首先,虚拟列是在11g中引入的,所以它不适用于任何早期数据库的人。更严重的问题是虚拟列受限于VARCHAR2列的4000个字符限制。再一次,它抛出了'ORA-54004'(谁知道OERR数字变得那么高?)。目前虚拟列不能是clobs。 – APC 2010-07-20 13:40:40

+0

@APC - 你是对的 - 我完全忽略了varchar2的限制,它减少了宽表的用处。感谢指向54004的指标 - 很高兴知道。 – dpbradley 2010-07-20 14:37:54