ВЫБЕРИТЕ КОЛИЧЕСТВО (*) по сравнению с выборкой дважды с явным курсором

Когда вы добавляете элемент на страницу, он не наследует функцию on 'change'. У вас также есть id = "produse", и у вас будут дублирующиеся идентификаторы ... Измените это на class = "produse" вместо Я бы! Что вам нужно сделать, это обернуть это в функцию ...

$("#addMore").click(function(){   
    $(".row-fluid:last").clone().appendTo(".wrapper"); 
    initiateProduse() // add the effect to new row
});
    function initiateProduse(){
     $(".produse").off("change"); // remove on change effects so it doesn't have double on change effects on existing rows...
     $(".produse").change(function(){
        var $this = $(this), value = $this.val(); // save value
        $('.sub_select_class').hide(); // we hide every second select
        switch(value) { // we show only what needs to be visible
           case 'Canapele':
             $("#ModeleCanapele").show();
             break;
           case 'Coltare':
             $("#ModeleColtare").show();
             break;
             case 'Mobila':
             $("#ModeleMobila").show();
             break;
             case 'Fotolii':
             $("#ModeleFotolii").show();
             break;
             case 'Seturi':
             $("#ModeleSeturi").show();
             break;
           // ...etc
        }
     });
    }

    initiateProduse() // initiate the change effect on page load

Теперь все еще будут проблемы ... Все эффекты шоу "#Modele ...." не будут работать, потому что есть повторяющиеся идентификаторы. Вам нужен способ указать, какой элемент вам нужно использовать ...

Я рекомендую атрибуты. Вы можете дать каждому select / input значение, например ModeleCanapele = "1", а затем, когда будет добавлена ​​вторая строка, будет ModeleCanapele = "2"

Тогда вы сделаете что-то вроде ...

$("[ModeleCanapele='"+newRowNumber+"']").show(); 

Вы можете отслеживать rowNumber, выполнив что-то вроде ...

<select class="produse" rowNumber="1"> 

для первого ...

и внутри новой функции, которую вы используете, вы можете сделать ...

var rowNumber = $(this).attr('rowNumber')
$('[sub_select_class="'+rowNumber+'"]').hide(); // change to attribute instead of class select 
switch(value) { // we show only what needs to be visible
           case 'Canapele':
             $("[ModeleCanapele='"+rowNumber+"']").show();
             break;

Чтобы установить НОВЫЙ номер строки, мы бы сделали что-то вроде этого ...

$("#addMore").click(function(){   
    var rows = $(".produse").length,
    newRowNumber = rows + 1
    $(".row-fluid:last").clone().appendTo(".wrapper")
    // make sure all of the rowNumber attributes = newRowNumber here
    initiateProduse() // add the effect to new row
});

У меня недостаточно времени, чтобы сделать весь код для вас, но это то, как вы можете это сделать. Вы должны убедиться, что каждый отдельный выбор / вход имеет атрибут & amp; идентификатор класса вместо идентификатора & amp; убедитесь, что номер строки добавляется (+1) каждый раз, когда вы добавляете строку

Намного проще было бы фактически включить шаблон HTML в JS, чтобы вы могли использовать переменную для установки нового номера строки каждый раз (вместо использования клона)

11
задан tshepang 29 May 2014 в 21:57
поделиться

8 ответов

Если два все, чем Вы интересуетесь, пробуете

SELECT 'THERE ARE AT LEAST TWO ROWS IN THE TABLE'
FROM DUAL
WHERE 2 =
(
    SELECT COUNT(*)
    FROM TABLE
    WHERE ROWNUM < 3
)

Потребуется меньше кода, чем выполнение ручного метода курсора, и это, вероятно, будет быстрее.

Прием rownum означает останавливать выбирающие строки, после того как он имеет двух из них.

Если Вы не помещаете своего рода предел на количество (*), это могло бы взять долго для окончания, в зависимости от количества строк, которые Вы имеете. В этом случае использование цикла курсора, для чтения 2 строк из таблицы вручную, было бы быстрее.

5
ответ дан 3 December 2019 в 03:05
поделиться

Перед взятием слишком серьезных предложений Steven Feuerstein просто немного сравните. Количество (*) заметно медленнее, чем явный курсор в Вашем случае? Нет? Затем лучшее использование конструкция, которая допускает простой, читаемый код. Который, в большинстве случаев, был бы "избранным количеством (*) в v_cnt... если v_cnt> 0 затем..."

МН / SQL допускает очень читаемые программы. Не тратьте впустую это только для нанооптимизирования.

1
ответ дан 3 December 2019 в 03:05
поделиться

В зависимости от DB может быть sys таблица, которая хранит приблизительное количество и может быть запрошена в постоянное время. Полезный, если Вы хотите знать, имеет ли таблица 20 строк или 20,000 или 20,000,000.

0
ответ дан 3 December 2019 в 03:05
поделиться

Он имеет в виду открытый курсор и выборка не только первая запись, но и второе, и затем Вы будете знать, что существует больше чем один.

Так как я никогда, кажется, не должен знать это SELECT COUNT(*) >= 2, Я понятия не имею, почему это - полезная идиома в любом варианте SQL. Или никакие записи или по крайней мере один, уверенный, но не два или больше. И так или иначе, всегда существует EXISTS.

Это и то, что оптимизатор Oracle, кажется, довольно плох... - я подверг бы сомнению уместность техники.

Обратиться к комментариям TheSoftwareJedi:

WITH CustomersWith2OrMoreOrders AS (
    SELECT CustomerID
    FROM Orders
    GROUP BY CustomerID
    HAVING COUNT(*) >= 2
)
SELECT Customer.*
FROM Customer
INNER JOIN CustomersWith2OrMoreOrders
    ON Customer.CustomerID = CustomersWith2OrMoreOrders.CustomerID

Соответственно индексированный, у меня никогда не было проблем производительности даже с целыми запросами вселенной как это в SQL Server. Однако я последовательно сталкивался с комментариями о проблемах с оптимизатором Oracle здесь и на других сайтах.

Мой собственный опыт с Oracle не был хорош.

В комментарии от OP, кажется, говорится что полный COUNT(*) от таблиц не хорошо обрабатываются оптимизатором. т.е.:

IF EXISTS (SELECT COUNT(*) FROM table_name HAVING COUNT(*) >= 2)
BEGIN
END

(который, то, когда первичный ключ существует, может быть уменьшено до простого индексного сканирования - в случае экстремальной оптимизации, можно просто запросить индексные метаданные в sysindexes.rowcnt - для нахождения количества записей - все без курсора), в пользу нужно обычно избегать:

DECLARE CURSOR c IS SELECT something FROM table_name;
BEGIN
    OPEN c
    FETCH c INTO etc. x 2 and count rows and handle exceptions
END;

IF rc >= 2 THEN BEGIN
END

Это, мне привело бы к меньше читаемому, менее портативному, и меньше удобного в сопровождении кода.

1
ответ дан 3 December 2019 в 03:05
поделиться

Это прибывает из написания кода программистов, подобного следующему (это - код psuedo!).

Вы хотите проверить, чтобы видеть, есть ли у клиента больше чем один порядок:

if ((select count(*) from orders where customerid = :customerid) > 1)
{
    ....
}

Это - ужасно неэффективный способ сделать вещи. Как Mark Brady сказал бы, если Вы хотите знать, содержит ли банка пенсы, Вы считали бы все пенсы в банке или просто удостоверились бы, что существует 1 (или 2 в Вашем примере)?

Это могло быть лучше записано как:

if ((select 1 from (select 1 from orders where customerid = :customerid) where rownum = 2) == 1)
{
    ....
}

Это предотвращает "подсчет всех монет" дилемма, так как Oracle выберет 2 строки, затем закончится. Предыдущий пример заставил бы оракула сканировать (индекс или таблица) для ВСЕХ строк, затем закончился бы.

3
ответ дан 3 December 2019 в 03:05
поделиться

Существует много причин, почему разработчики могли бы выполнить избранное КОЛИЧЕСТВО (*) от таблицы в МН программе / программе SQL:

1) Они действительно должны знать, сколько строк там находится в таблице.

В этом случае нет никакого выбора: выберите КОЛИЧЕСТВО (*) и ожидайте результата. Это будет довольно быстро на многих таблицах, но могло требовать времени на большой таблице.

2) Они просто должны знать, существует ли строка или нет.

Это не гарантирует подсчет всех строк в таблице. Много методов возможны:

a) Явный метод курсора:

DECLARE
   CURSOR c IS SELECT '1' dummy FROM mytable WHERE ...;
   v VARCHAR2(1);
BEGIN
   OPEN c;
   FETCH c INTO v;
   IF c%FOUND THEN
      -- A row exists
      ...
   ELSE
      -- No row exists
      ...
   END IF;
END;

b) ВЫБЕРИТЕ В метод

DECLARE
   v VARCHAR2(1);
BEGIN
   SELECT '1' INTO v FROM mytable 
   WHERE ... 
   AND ROWNUM=1; -- Stop fetching if 1 found
   -- At least one row exists
EXCEPTION
   WHEN NO_DATA_FOUND THEN
      -- No row exists
END;

c) ВЫБЕРИТЕ КОЛИЧЕСТВО (*) с методом ROWNUM

DECLARE
   cnt INTEGER;
BEGIN
   SELECT COUNT(*) INTO cnt FROM mytable 
   WHERE ... 
   AND ROWNUM=1; -- Stop counting if 1 found
   IF cnt = 0 THEN
      -- No row found
   ELSE
      -- Row found
   END IF;
END;

3) Они должны знать, существует ли больше чем 1 строка.

Вариации на методы для (2) работа:

a) Явный метод курсора:

DECLARE
   CURSOR c IS SELECT '1' dummy FROM mytable WHERE ...;
   v VARCHAR2(1);
BEGIN
   OPEN c;
   FETCH c INTO v;
   FETCH c INTO v;
   IF c%FOUND THEN
      -- 2 or more rows exists
      ...
   ELSE
      -- 1 or 0 rows exist
      ...
   END IF;
END;

b) ВЫБЕРИТЕ В метод

DECLARE
   v VARCHAR2(1);
BEGIN
   SELECT '1' INTO v FROM mytable 
   WHERE ... ;
   -- Exactly 1 row exists
EXCEPTION
   WHEN NO_DATA_FOUND THEN
      -- No row exists
   WHEN TOO_MANY_ROWS THEN
      -- More than 1 row exists
END;

c) ВЫБЕРИТЕ КОЛИЧЕСТВО (*) с методом ROWNUM

DECLARE
   cnt INTEGER;
BEGIN
   SELECT COUNT(*) INTO cnt FROM mytable 
   WHERE ... 
   AND ROWNUM <= 2; -- Stop counting if 2 found
   IF cnt = 0 THEN
      -- No row found
   IF cnt = 1 THEN
      -- 1 row found
   ELSE
      -- More than 1 row found
   END IF;
END;

Какой метод, который Вы используете, является в основном вопросом предпочтения (и некоторый религиозный фанатизм!) Steven Feuerstein всегда одобрял явные курсоры по неявному (ВЫБОР В и курсор ДЛЯ циклов); Tom Kyte одобряет неявные курсоры (и я соглашаюсь с ним).

Важный момент - то, что для выбора КОЛИЧЕСТВА (*), не ограничивая ROWCOUNT является дорогим и должно поэтому только быть сделано, когда количество действительно необходимо.

Что касается Вашего дополнительного вопроса о том, как переписать это с явным курсором:

CREATE OR REPLACE PROCEDURE do_sth ( emp_id_in IN emp.emp_id%TYPE )
IS
v_rows INTEGER;
BEGIN
    ...

    SELECT COUNT(*) INTO v_rows
    FROM emp
    WHERE emp_id = emp_id_in;

    IF v_rows > 0 THEN
        /* do sth */
    END;

    /* more statements */
    ...

END do_sth;

Это было бы:

CREATE OR REPLACE PROCEDURE do_sth ( emp_id_in IN emp.emp_id%TYPE )
IS
    CURSOR c IS SELECT 1
                FROM emp
                WHERE emp_id = emp_id_in;
    v_dummy INTEGER;
BEGIN
    ...

    OPEN c;    
    FETCH c INTO v_dummy;
    IF c%FOUND > 0 THEN
        /* do sth */
    END;
    CLOSE c;

    /* more statements */
    ...

END do_sth;

Но действительно, в Вашем примере это не лучше или хуже, так как Вы выбираете первичный ключ, и Oracle достаточно умна, чтобы знать, что это только должно выбрать однажды.

22
ответ дан 3 December 2019 в 03:05
поделиться

SQL Server:

if 2 = (
    select count(*) from (
        select top 2 * from (
            select T = 1 union
            select T = 2 union
            select T = 3 ) t) t)
    print 'At least two'

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

-1
ответ дан 3 December 2019 в 03:05
поделиться

Если бы Вы хотите получить количество строк в таблице, не проводите используемый подсчет (*), я предложил бы количество (0), которое 0 является индексом столбца Вашего столбца первичного ключа.

-2
ответ дан 3 December 2019 в 03:05
поделиться
Другие вопросы по тегам:

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