Несколько операторов «in» в предложении where, которые должны совпадать друг с другом - PullRequest
3 голосов
/ 04 января 2012

У меня очень длинный запрос, который по сути является расширением следующего:

update  property.lease_period
set     scca_uplift = '110',
        scca_notes_code = '21006'
where   (suite_id = 'CCBG08' and lease_id = '205059')
        or (suite_id = 'CCBG14' and lease_id = '152424')
        or (suite_id = 'CCCF048' and lease_id = '150659')

Предложение where для этого будет иметь ~ 40 строк после завершения.Чтобы упростить эту задачу, я надеялся сделать что-то похожее на следующее:

update  property.lease_period
set     scca_uplift = '110',
        scca_notes_code = '21006'
where   suite_id in('CCBG08', 'CCBG14', 'CCCF048')
        and lease_id in('205059', '152424', '150659')

К сожалению, lease_id не является уникальным полем, и к одному и тому же suite_id может быть несколько lease_id (так что в последующемзапрос не может быть использован).

Есть ли лучший способ сделать первый оператор обновления, если это решение не будет работать?

Ответы [ 4 ]

3 голосов
/ 04 января 2012

Вы можете создать тип таблицы и передать через него значения, например:

CREATE TYPE Suite_Lease AS TABLE
(
suite_id varchar(15) NOT NULL,
lease_id varchar(15) NOT NULL
)
GO
CREATE PROC DoUpdate
  @Params Suite_Lease READONLY,
  @uplift varchar(15),
  @code varchar(15)
AS
  update  property.lease_period  set
     scca_uplift = @uplift,
     scca_notes_code = @code
  from property.lease_period tab
  JOIN @params filt
    on tab.suite_id=filt.suite_id AND tab.lease_id=filt.lease_id

Это сохранит ваш кэш процедур сухим и чистым, вместо этого, если вы используете несколько больших"where clauses

Как передать параметр таблицы в хранимую процедуру (c #):

        DataTable dt = new DataTable();
        dt.Columns.Add(new DataColumn("suite_id", typeof (string)) {AllowDBNull = false, MaxLength = 15});
        dt.Columns.Add(new DataColumn("lease_id", typeof (string)) {AllowDBNull = false, MaxLength = 15});
        dt.Rows.Add("CCBG08", "205059");

        ... add more rows for match

        using (var c = new SqlConnection("ConnectionString"))
        {
            c.Open();
            using(var sc = c.CreateCommand())
            {
                sc.CommandText = "DoUpdate";
                sc.CommandType = CommandType.StoredProcedure;
                sc.Parameters.AddWithValue("@uplift", "110");
                sc.Parameters.AddWithValue("@code", "21006");
                sc.Parameters.Add(new SqlParameter("@Params", SqlDbType.Structured) { TypeName = null, Value = dt });
                sc.ExecuteNonQuery();
            }
        }
1 голос
/ 04 января 2012

Попробуйте это

update  property.lease_period
set     scca_uplift = '110',
        scca_notes_code = '21006'
where   (suite_id in,lease_id) in 
        (select   suite_id in,lease_id from XXX_table where CONDITION)

Последний SELECT должен дать вам эти 40 комбинаций.

1 голос
/ 04 января 2012

Используя трюк из этой статьи . Это выглядит немного некрасиво, но делает свое дело:

update property.lease_period
set scca_uplift = @uplift, scca_notes_code = @code
from property.lease_period tab
JOIN (
    select 'CCBG08' as suite_id, '205059' as lease_id union all
    select 'CCBG14', '152424' union all
    select 'CCCF048', '150659'
) xxx
on tab.suite_id=xxx.suite_id AND tab.lease_id=xxx.lease_id
0 голосов
/ 04 января 2012

Полученный из комментария @dasblinkenlight (для Oracle), другой возможный способ сделать это будет следующим:

select  *
from    property.lease_period
where   (suite_id + ' ' + lease_id) 
        in (
            ('CCBG08 205059'),
            ('CCBG14 152424'),
            ('CCCF048 150659')
        )

Это не очень рекомендуется, так как это плохо для индексации (конкатенация в MicrosoftSQL), но я все равно подумал, что это интересно.

dasblinkenlights оригинальный комментарий:

@ Майкл, я бы хотел, чтобы ты спрашивал об Oracle, он намного чище там: вы делаете где (lease_period, lease_id) в ((«CCBG08», «205059»), («CCBG14», «152424»), («CCCF048», «150659»)) и делает трюк. Почему SQL Server не может этого сделать, я не знаю. -

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...