Каково ограничение в длине запроса SqlCommand

Если вы хотите сослаться на предыдущие изменения в объектах ActiveRecord (после того, как изменения сохранятся и объект будет перезагружен), я рекомендую создать отдельную таблицу (например, product_dirties) для отслеживания указанных изменений. Давайте используем вашу модель Product в качестве примера:

Сначала вы захотите создать таблицу product_dirties

create_table :product_dirties do |t|
  t.references :product,      index: true, foreign_key: true
  t.jsonb      :modifications
end

Затем добавьте модель ProductDirty

class ProductDirty < ApplicationRecord
  belongs_to :product, inverse_of: :product_dirties

  validates_presence_of :product, :modifications
end

И обновите свою модель Product, чтобы включить новую ассоциацию и обратный вызов для создания грязных записей при внесении изменений:

class Product < ApplicationRecord
  has_many :product_dirties, inverse_of: :product

  before_save :create_dirty_record, if: -> { changed? }

  private

  def create_dirty_record
    # modifications will be saved in this format: {"name"=>"new name here!"}
    attribute_changes = ActiveSupport::HashWithIndifferentAccess[self.changed.map{ |attr| [attr, self.method(attr).call] }]

    if attribute_changes.present?
      ProductDirty.find_or_create_by(product: self).update_attribute(:modifications, attribute_changes)
    end

    self.restore_attributes # <- add this if you'd like to revert the changes to the product and keep them separate in the `product_dirties` table
  end
end

Затем вы можете добавить метод в свой Product модель, которая делает поиск изменений. Мы добавили метод apply_dirty_record (см. Ниже) к нашей родительской модели (например, Product), так как мы фактически не сохраняем изменения (см. Примечание рядом с self.restore_attributes выше).

def apply_dirty_record
  dirty_record = ProductDirty.find_by(product: self)
  self.assign_attributes(dirty_record.modifications) if dirty_record
end
7
задан Michael Prewecki 3 December 2008 в 00:01
поделиться

6 ответов

SqlServer 2000 имеет 4 000 символьных пределов запроса для специальных запросов.

Действительно ли можно ли абстрагировать это в хранимую процедуру?

6
ответ дан 6 December 2019 в 09:23
поделиться

Вот мысль:

VARCHAR 2000-х SQLServer позволяет до 8 000 символов, таким образом, это могло бы работать:

PSeudoCode:

SQLCommand command = new SqlCommand("exec sp_executeSQL @CMD");
command.Parameters.Add(new SqlParameter("@CMD",YourDynamicSQL, VARCHAR);
6
ответ дан 6 December 2019 в 09:23
поделиться

Я столкнулся с пределом 2k для запросов, выполненных против AS/400. Мне обычно удавалось добраться под пределом 2k путем удаления всего пробела - он делает запрос нечитабельным, но это - самый простой способ добраться под пределом.

2
ответ дан 6 December 2019 в 09:23
поделиться

необходимость чтение для динамических запросов... Проклятие и Благословения Динамического SQL, я настоятельно рекомендую, чтобы Вы считали его. Не мог бы помочь Вам на этот раз, но это определенно поможет Вам в будущем..

Кавычка от статьи, на всякий случай.

sp_executesql и Длинные Строки SQL в SQL 2000

Существует ограничение с sp_executesql на SQL 2000 и SQL 7, так как Вы не можете использовать более длинные строки SQL, чем 4 000 символов. (На SQL 2005 и позже, необходимо использовать nvarchar (МАКС) для предотвращения этой проблемы.), Если Вы хотите использовать sp_executesql, когда Ваша строка запроса превышает этот предел для использования планов параметризированного запроса, существует на самом деле обходное решение. К остроумию можно перенести sp_executesql в ДОЛЖНОСТНОЕ ЛИЦО ():

ОБЪЯВИТЕ @sql1 nvarchar (4000), @sql2 nvarchar (4000), @state символ (2) ВЫБОР @state =, 'CA' ВЫБИРАЕТ @sql1 =, КОЛИЧЕСТВО N'SELECT (*)' ВЫБИРАЕТ @sql2 = N'FROM dbo.authors ГДЕ состояние = @state' ДОЛЖНОСТНОЕ ЛИЦО ('ДОЛЖНОСТНОЕ ЛИЦО sp_executesql N''' + @sql1 + @sql2 + '' ', N'' @state символ (2)'', @state = ''' + @state +' '' ')

Это работает, потому что @stmt параметр к sp_executesql является ntext, так отдельно, он не имеет никакого ограничения в размере.

Можно даже использовать выходные параметры при помощи ВСТАВЛЯТЬ-ДОЛЖНОСТНОГО-ЛИЦА, как в этом примере:

CREATE TABLE #result (cnt международный NOT NULL) ОБЪЯВЛЯЕТ @sql1 nvarchar (4000), @sql2 nvarchar (4000), @state символ (2), @mycnt интервал ВЫБИРАЮТ @state =, 'CA' ВЫБИРАЕТ @sql1 = N'SELECT @cnt =, КОЛИЧЕСТВО (*)' ВЫБИРАЕТ @sql2 = N'FROM dbo.authors, ГДЕ состояние = @state' ВСТАВЛЯЕТ #result (cnt), ДОЛЖНОСТНОЕ ЛИЦО ('ОБЪЯВЛЯЮТ @cnt международное ДОЛЖНОСТНОЕ ЛИЦО sp_executesql N''' + @sql1 + @sql2 + '' ', N'' @state символ (2), @cnt международный ВЫВОД'', @state = ''' + @state + '' ', @cnt = @cnt ВЫХОДНОЙ ВЫБОР @cnt'), ВЫБИРАЮТ @mycnt = cnt ОТ #result

У Вас есть мое понимание, если Вы думаете, что это слишком грязно для ценности того.

6
ответ дан 6 December 2019 в 09:23
поделиться

Не делайте, чтобы сделать это из-за внедрений SQL. Откажитесь от этого, если динамическим sql приложения может управлять вообще пользователь.

также - полагают, что SP начиная с его более легкого поддерживает, и он также помогает с внедрением SQL.

-2
ответ дан 6 December 2019 в 09:23
поделиться

В моем собственном опыте я нашел, что, то, что сначала, казалось, было пределом SQLServer2000 на длину запросов, было на самом деле (хотите верьте, хотите нет), не действительно пределом на длину запроса, но, является пределом на длину любой данной СТРОКИ в запросе.
Это было приблизительно год назад, когда я столкнулся с этим, так первое, что пришло на ум я не помню, какова длина строки была, но Вы могли попытаться разделить огромный запрос на строки макс. длины строки 64K или поблизости и видеть, как это идет. Мое воспоминание, что предел длины строки, возможно, был 64K, хотите верьте, хотите нет. Я взял этот безумно долгий запрос (был сгенерирован программой sql-генератора), запрос был о 80K долго, и я разделил его в половине в Блокноте (т.е. я поместил перевод строки в код SQL приблизительно в средней точке---, но я удостоверился, что не разделил любые слова), и затем вставил все это в командное окно Query Analyzer. Затем это работало, имея перевод строки где-нибудь в середине, таким образом вызывающей каждую из этих 2 строк быть меньше, чем 64K долго. Я надеюсь, что это помогает. В противном случае попробуйте меньшие длины строки. Я уверен, что то, когда я получил свой запрос до такой степени, когда никакая строка в нем, превысило определенную длину, полный запрос работал.

2
ответ дан 6 December 2019 в 09:23
поделиться
Другие вопросы по тегам:

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