Проверьте, существует ли строка, иначе вставьте

1114 Да, вы правильно поняли.

Использование 64-битного IEDriverServer.exe send_keys() заполняет поле с последовательностью символов очень медленно.

@JimEvans в статье упоминаются скриншоты, SendKeys и шестьдесят четыре бита Существует несколько проблем с драйвером Internet Explorer, которые существовали с момента выхода IE10 .

Комментарии в обсуждении. Медленная типизация IE x64 упоминает, что для любого исправления потребуется «массивная реархитектура двоичных компонентов драйвера IE, [поэтому] временная шкала (или не будет) доступна» для доставки исправления. Что вызывает эти проблемы? Как они связаны? Почему исправление так чертовски сложно? Все ответы на эти вопросы можно суммировать с помощью простого ответа: «Windows Hooks».

Анализ

Когда вы работаете с IE 10 или выше на 64 версия Windows, по умолчанию процесс, в котором размещается содержащее окно, включающее браузер Chrome (адресная строка, кнопки навигации, меню и т. д.), является 64-разрядным процессом. Процесс, в котором размещается окно, в котором фактически отображается контент (внутри каждой вкладки), является 32-битным процессом.

По умолчанию драйвер IE пытается использовать хук окон в окне визуализации контента, чтобы убедиться, что сообщение о нажатии клавиши должным образом обрабатывается перед отправкой сообщения о ключе. Вот где проблема. Хук Windows не установлен, потому что 32-битный процесс (процесс рендеринга контента) не может выполнить 64-битный код. Единственный способ исправить это - создать второй (32-разрядный) исполняемый файл для ожидания завершения нажатия клавиши. Поскольку это может привести к масштабной реархитектуре двоичных компонентов драйвера IE, временная шкала не доступна (или не будет) для этого изменения. Это означает, что даже когда вы работаете с 64-битной Windows, вы, вероятно, используете 32-битную версию IE для рендеринга контента. Это мощный аргумент для продолжения использования 32-битной версии драйвера IE для IE 10 и выше: на самом деле вы не работаете с 64-битной версией IE.

Если вы настаиваете на необходимости запуска 64-битной версии IEDriverServer.exe, у вас есть два возможных обходных пути. Во-первых, вы можете отключить нативные события, установив для «nativeEvents» значение false, используя любой механизм, предусмотренный для этого вашей языковой привязкой. Более точный обходной путь с точки зрения имитации ввода мог бы заключаться в том, чтобы включить возможность «requireWindowFocus», хотя это также имеет зависимость от крючка окон, которая может проявляться и другими способами.

Windows Hook

Все приложения Windows содержат подпрограмму, называемую «цикл обработки сообщений». Цикл сообщений повторно вызывает функцию API GetMessage и обрабатывает сообщения, отправленные приложению, по мере их поступления в его очередь. Хуки - это функция системы обработки сообщений Windows, которая позволяет разработчику перехватывать, проверять и изменять сообщение, отправляемое приложению. Установив хук, разработчик может, например, проверить, что определенное сообщение было обработано перехватываемым окном. Или они могут изменить сообщение, отправленное в окно, чтобы показать, что операционная система может делать то, что на самом деле не может. Это умный механизм, но у него есть несколько требований, которые выходят за рамки этого обсуждения.

Решение

Вместо 64-разрядного IEDriverServer.exe начать использовать 32-разрядный IEDriverServer.exe


Где разместить IEDriverServer.exe?

Вы можете поместить IEDriverServer.exe в любое место вашей системы и передать абсолютное местоположение двоичного файла через аргумент executable_path следующим образом ( Пример ОС Windows):

from selenium import webdriver

driver = webdriver.Ie(executable_path=r'C:\path\to\IEDriverServer.exe')
driver.get("https://www.facebook.com/")
print("Page Title is : %s" %driver.title)
driver.quit()

225
задан Whymarrh 15 April 2017 в 17:38
поделиться

5 ответов

Смотрите на СЛИЯНИЕ команда. Можно сделать UPDATE, INSERT & DELETE в одном операторе.

Вот рабочая реализация при использовании MERGE
- Это проверяет, полон ли полет прежде, чем сделать обновление, еще делает вставку.

if exists(select 1 from INFORMATION_SCHEMA.TABLES T 
              where T.TABLE_NAME = 'Bookings') 
begin
    drop table Bookings
end
GO

create table Bookings(
  FlightID    int identity(1, 1) primary key,
  TicketsMax    int not null,
  TicketsBooked int not null
)
GO

insert  Bookings(TicketsMax, TicketsBooked) select 1, 0
insert  Bookings(TicketsMax, TicketsBooked) select 2, 2
insert  Bookings(TicketsMax, TicketsBooked) select 3, 1
GO

select * from Bookings

И затем...

declare @FlightID int = 1
declare @TicketsToBook int = 2

--; This should add a new record
merge Bookings as T
using (select @FlightID as FlightID, @TicketsToBook as TicketsToBook) as S
    on  T.FlightID = S.FlightID
      and T.TicketsMax > (T.TicketsBooked + S.TicketsToBook)
  when matched then
    update set T.TicketsBooked = T.TicketsBooked + S.TicketsToBook
  when not matched then
    insert (TicketsMax, TicketsBooked) 
    values(S.TicketsToBook, S.TicketsToBook);

select * from Bookings
154
ответ дан potashin 23 November 2019 в 03:55
поделиться

Я принимаю одну строку для каждого полета? Раз так:

IF EXISTS (SELECT * FROM Bookings WHERE FLightID = @Id)
BEGIN
    --UPDATE HERE
END
ELSE
BEGIN
   -- INSERT HERE
END

я принимаю то, что я сказал, поскольку Ваш способ сделать вещи может перебронировать полет, поскольку он вставит новую строку, когда будет 10 билетов макс., и Вы заказываете 20.

150
ответ дан Gregory A Beamer 23 November 2019 в 03:55
поделиться

Это - что-то, что я просто недавно должен был сделать:

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[cjso_UpdateCustomerLogin]
    (
      @CustomerID AS INT,
      @UserName AS VARCHAR(25),
      @Password AS BINARY(16)
    )
AS 
    BEGIN
        IF ISNULL((SELECT CustomerID FROM tblOnline_CustomerAccount WHERE CustomerID = @CustomerID), 0) = 0
        BEGIN
            INSERT INTO [tblOnline_CustomerAccount] (
                [CustomerID],
                [UserName],
                [Password],
                [LastLogin]
            ) VALUES ( 
                /* CustomerID - int */ @CustomerID,
                /* UserName - varchar(25) */ @UserName,
                /* Password - binary(16) */ @Password,
                /* LastLogin - datetime */ NULL ) 
        END
        ELSE
        BEGIN
            UPDATE  [tblOnline_CustomerAccount]
            SET     UserName = @UserName,
                    Password = @Password
            WHERE   CustomerID = @CustomerID    
        END

    END
2
ответ дан TheTXI 23 November 2019 в 03:55
поделиться

Вы могли использовать Слияние Функциональность для достижения. Иначе можно сделать:

declare @rowCount int

select @rowCount=@@RowCount

if @rowCount=0
begin
--insert....
1
ответ дан Ry- 23 November 2019 в 03:55
поделиться

Передавать подсказки обновления, блокировки строк и блокировки при проверке существования строки.

begin tran /* default read committed isolation level is fine */

if not exists (select * from Table with (updlock, rowlock, holdlock) where ...)
    /* insert */
else
    /* update */

commit /* locks are released here */

Подсказка обновления заставляет запрос принять блокировку обновления для строки, если она уже существует, не позволяя другим транзакциям изменять ее до тех пор, пока вы не зафиксируете или не откатитесь.

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

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

См. http://msdn.microsoft.com/en-us/library/ms187373.aspx для получения дополнительной информации.

Обратите внимание, что блокировки принимаются как выполняемые операторы, которые их принимают - вызов begin tran не дает вам иммунитета от другой транзакции, блокирующей что-либо до того, как вы доберетесь до этого. Вы должны попытаться использовать фактор SQL для удержания блокировок в течение как можно более короткого времени, зафиксировав транзакцию как можно скорее (приобретение поздно, освобождение раньше).

Обратите внимание, что блокировки на уровне строк могут быть менее эффективными, если ваш PK является bigint, поскольку внутреннее хеширование на SQL Server является вырожденным для 64-битных значений (разные значения ключей могут хешировать один и тот же идентификатор блокировки).

64
ответ дан 23 November 2019 в 03:55
поделиться
Другие вопросы по тегам:

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