Надлежащий способ обработать 'дополнительный', где пункт просачивается SQL?

Даже если Вы получаете keydown / keyup событие, те - единственные события, которые запускает клавиша Tab, Вам все еще нужен некоторый способ предотвратить действие по умолчанию, перемещаясь в следующий объект в порядке вкладки, от появления.

В Firefox можно звонить preventDefault(), метод на объекте-событии передал обработчику событий. В IE необходимо возвратить false от дескриптора события. Библиотека JQuery обеспечивает preventDefault метод на его объекте-событии, который работает в IE и И следующие

<body>
<input type="text" id="myInput">
<script type="text/javascript">
    var myInput = document.getElementById("myInput");
    if(myInput.addEventListener ) {
        myInput.addEventListener('keydown',this.keyHandler,false);
    } else if(myInput.attachEvent ) {
        myInput.attachEvent('onkeydown',this.keyHandler); /* damn IE hack */
    }

    function keyHandler(e) {
        var TABKEY = 9;
        if(e.keyCode == TABKEY) {
            this.value += "    ";
            if(e.preventDefault) {
                e.preventDefault();
            }
            return false;
        }
    }
</script>
</body>
6
задан 2 revs 10 November 2009 в 07:22
поделиться

5 ответов

Если мы преобразуем SQL в строку, а затем вызовем для нее sp_ExecuteSQL, чтение будет почти нулевым ...

  1. Поскольку ваш запрос больше не оценивает операцию ИЛИ, что, как вы можете см. kills sargability
  2. План запроса кэшируется при использовании sp_executesql; SQL Server не должен выполнять жесткий синтаксический анализ ...

Превосходный ресурс: Проклятие и благословение динамического SQL

Пока вы используете параметризованные запросы, вы должны избегать SQL Инъекционные атаки .

4
ответ дан 17 December 2019 в 02:30
поделиться

Это еще одна разновидность техники необязательных параметров:

SELECT * FROM dbo.MyTableName t1
WHERE t1.ThisField = 'test'
AND t1.MyField = COALESCE(@MyOptionalParam, t1.MyField)

Я почти уверен, что у нее будет такая же проблема с производительностью. Если производительность - №1, то вы, вероятно, застрянете с логикой разветвления и рядом с дублирующимися запросами или построением строк, что не менее болезненно в TSQL.

2
ответ дан 17 December 2019 в 02:30
поделиться

You're using "OR" clause (implicitly and explicitly) on the first two SQL statements. Last one is an "AND" criteria. "OR" is always more expensive than "AND" criteria. No you're not crazy, should be expected.

1
ответ дан 17 December 2019 в 02:30
поделиться

Измените использование синтаксиса «или» на подход с двумя запросами, вы увидите 2 разных плана, которые следует сохранить ваш логический счетчик чтения как можно меньше:

IF @MyOptionalParam is null
BEGIN

  SELECT *
  FROM dbo.MyTableName t1

END
ELSE
BEGIN

  SELECT *
  FROM dbo.MyTableName t1
  WHERE t1.MyField = @MyOptionalParam

END

Вам нужно бороться с желанием вашего программиста уменьшить дублирование здесь. Поймите, что вы запрашиваете два принципиально разных плана выполнения и требуете два запроса для создания двух планов.

-1
ответ дан 17 December 2019 в 02:30
поделиться

РЕДАКТИРОВАТЬ: Добавление ссылка на аналогичный вопрос / ответ с контекстом о том, почему подход union / if ... else работает лучше, чем логика OR (FYI, Ремус, ответчик в этой ссылке, использовался для работы с командой разработчиков SQL Server, занимающейся разработкой сервис-брокера и другие технологии)

При переходе от использования синтаксиса «или» к подходу объединения вы увидите 2 поиска, которые должны поддерживать как можно меньшее количество логических считываний:

SELECT * FROM dbo.MyTableName t1
WHERE t1.ThisField = 'test'
AND @MyOptionalParam IS NULL 
union all
SELECT * FROM dbo.MyTableName t1
WHERE t1.ThisField = 'test'
AND t1.MyField = @MyOptionalParam

Если вы хотите исключить дублирование результатов используйте «union» вместо «union all».

EDIT: демонстрация, показывающая, что оптимизатор достаточно умен, чтобы исключить сканирование с нулевым значением переменной в UNION:

if object_id('tempdb..#data') > 0
    drop table #data
go

-- Put in some data
select  top 1000000
        cast(a.name as varchar(100)) as thisField, cast(newid() as varchar(50)) as myField
into    #data
from    sys.columns a
cross join sys.columns b
cross join sys.columns c;
go

-- Shwo count
select count(*) from #data;
go

-- Index on thisField
create clustered index ixc__blah__temp on #data (thisField);
go

set statistics io on;
go

-- Query with a null parameter value
declare @MyOptionalParam varchar(50);
select  *
from    #data d 
where   d.thisField = 'test'
and     @MyOptionalParam is null;
go

-- Union query
declare @MyOptionalParam varchar(50);
select  *
from    #data d 
where   d.thisField = 'test'
and     @MyOptionalParam is null
union all
select  *
from    #data d 
where   d.thisField = 'test'
and     d.myField = '5D25E9F8-EA23-47EE-A954-9D290908EE3E';
go

-- Union query with value
declare @MyOptionalParam varchar(50);
select @MyOptionalParam = '5D25E9F8-EA23-47EE-A954-9D290908EE3E'
select  *
from    #data d 
where   d.thisField = 'test'
and     @MyOptionalParam is null
union all
select  *
from    #data d 
where   d.thisField = 'test'
and     d.myField = '5D25E9F8-EA23-47EE-A954-9D290908EE3E';
go

if object_id('tempdb..#data') > 0
    drop table #data
go
0
ответ дан 17 December 2019 в 02:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: