在字段中进行搜索的最佳方式

时间:2015-08-12 14:48:16

标签: sql-server tsql sql-server-2012

我正在编写一个查询来搜索单个字段中的特定字符串,该字段是一个大的XML字符串。我不确定最好的办法是什么。以下是目前的查询:

use Database
SELECT * From Table1 with (nolock) 
where date_received >= '20150805'
and date_received < '20150807'
and xml_msg in ('ID1008421','ID2','ID3','ID4',etc for 20 more)

由于显而易见的原因,它不会返回任何数据。对于我想要发生的事情,这只是一种伪代码。

我正在考虑做一个类似的查询,但我必须为每个InstrumentId做一个。严重破碎的xml看起来像这样:

<?xml version="1.0"?>
<Pro>  
    <Header>
        <DestinationID>ABC</DestinationID>
        <SenderID>DEF</SenderID>
        <ClientBank>GHI</ClientBank>
        <OperationOrganizationID>BLT1</OperationOrganizationID>
        <MessageType>BALMIS</MessageType>
        <DateSent>20150805</DateSent>
        <TimeSent>131307</TimeSent>
        <MessageID>1073586000</MessageID>
    </Header>
    <SubHeader>
        <InstrumentID>ID1008421</InstrumentID>
        <InstrumentStatus>ACT</InstrumentStatus>
        <ActivityType>COL</ActivityType>
        <ActivityStatus>REL</ActivityStatus>
        <BusinessDate>20150805</BusinessDate>
        <OriginalActivityType>COL</OriginalActivityType>
        <ProductType>INC</ProductType>
        <Product>DCO</Product>
        <ProductCategory>CO</ProductCategory>
        <RelationshipCustomerID>CHABC01818</RelationshipCustomerID>
        <LimitCustomerID>SBMYQRST01</LimitCustomerID>
        <BaseCurrency>USD</BaseCurrency>
        <InstrumentCurrency>USD</InstrumentCurrency>
        <LimitCurrency>USD</LimitCurrency>
        <MessageSequenceNumber>000000004567868</MessageSequenceNumber>
    </SubHeader>
    <Body>
        <Activity>
            <DateActivity>20150804</DateActivity>
            <ActivitySequenceNo>1</ActivitySequenceNo>
            <SequenceDate>20150805</SequenceDate>
            <SequenceTime>131306</SequenceTime>
        </Activity>
    </Body>
</Pro>

除了,它是一个大字符串。这是表的DDL,如果有帮助的话。

CREATE TABLE [dbo].[TABLE1](
    [out_interface_id] [int] IDENTITY(1,1) NOT NULL,
    [msg_id] [char](10) NOT NULL,
    [msg_type] [char](7) NOT NULL,
    [xml_msg] [varchar](max) NOT NULL,
    [date_received] [datetime] NOT NULL,
    [status] [varchar](10) NOT NULL,
    [last_modified] [datetime] NOT NULL,
    [environment] [char](4) NULL,
    [transaction_closed_date] [smalldatetime] NULL,
 CONSTRAINT [idx_pk_TABLE1] PRIMARY KEY CLUSTERED 
(
    [out_interface_id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

这是在新的SQL 2k12服务器上运行的。我只能使用T-sql代码来执行此操作。我无法写任何存储过程。

谢谢,

马特

2 个答案:

答案 0 :(得分:0)

在像这样的大型varchar领域,你可以做到

select * from Table1
where date_received >= '20150805'
and date_received < '20150807' 
and
(
xml_msg like '%ID1VALUE%' or
xml_msg like '%ID2VALUE%' or 
...
)

这将在运行时杀死您的数据库性能。

如果您可以修改Table1,您应该为它添加一个InstrumentID字段,因为这是您搜索的内容,并在每次添加xml消息时填充该值(看起来您现在正在为messageID执行此操作)和那么你在部分工作

select * from Table1
where date_received >= '20150805'
and date_received < '20150807' 
and instrumentID in
(
    'ID1VALUE',
    'ID2VALUE',  
    ...
)

答案 1 :(得分:0)

如果你想让你的DBA来追捕你,你当然可以

INSERT INTO MY_ID_SEARCH_TABLE ( ID_TO_SEARCH_FOR ) VALUES ( 'ID1008421' );
INSERT INTO MY_ID_SEARCH_TABLE ( ID_TO_SEARCH_FOR ) VALUES ( 'ID2' );
INSERT INTO MY_ID_SEARCH_TABLE ( ID_TO_SEARCH_FOR ) ...


SELECT t1.*
From Table1 t1
inner join MY_ID_SEARCH_TABLE mist
on t1.xml_msg like
  '%<InstrumentID>' + mist.ID_TO_SEARCH_FOR + '</InstrumentID>%'