Как я должен передать имя таблицы в сохраненный proc?

Все объекты в JavaScript реализованы как хеш-таблицы/ассоциативные массивы. Так, следующее эквивалент:

alert(myObj["SomeProperty"]);
alert(myObj.SomeProperty);

И, как уже обозначено, Вы "удаляете" свойство из объекта через delete ключевое слово, которое можно использовать двумя способами:

delete myObj["SomeProperty"];
delete myObj.SomeProperty;

Hope дополнительная информация помогает...

14
задан Beska 26 January 2010 в 14:19
поделиться

7 ответов

Прежде всего, вы должны НИКОГДА не выполнять композиции команд SQL в клиентском приложении, подобном этому, это , что такое SQL-инъекция. (Это нормально для инструмента администрирования, у которого нет собственных привилегий, но не для приложения для совместного использования.)

Во-вторых, да, параметризованный вызов хранимой процедуры и чище, и безопаснее.

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

Вот простой наивный пример:

CREATE PROC spCountAnyTableRows( @PassedTableName as NVarchar(255) ) AS
-- Counts the number of rows from any non-system Table, *SAFELY*
BEGIN
    DECLARE @ActualTableName AS NVarchar(255)

    SELECT @ActualTableName = QUOTENAME( TABLE_NAME )
    FROM INFORMATION_SCHEMA.TABLES
    WHERE TABLE_NAME = @PassedTableName

    DECLARE @sql AS NVARCHAR(MAX)
    SELECT @sql = 'SELECT COUNT(*) FROM ' + @ActualTableName + ';'

    EXEC(@SQL)
END

У некоторых есть справедливо спросил, почему это безопаснее. Надеюсь, маленькие таблицы Бобби могут прояснить это:

alt text


Ответы на другие вопросы:

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

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

41
ответ дан 1 December 2019 в 06:16
поделиться

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

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

5
ответ дан 1 December 2019 в 06:16
поделиться

Я бы возражал против динамической генерации SQL в хранимой процедуре; это доставит вам неприятности и может вызвать уязвимость для инъекций.

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

2
ответ дан 1 December 2019 в 06:16
поделиться

Похоже, вам было бы лучше с решением ORM.

Я съеживаюсь, когда вижу динамический sql в хранимой процедуре.

2
ответ дан 1 December 2019 в 06:16
поделиться

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

1) если они одинаковые, почему бы не создать новый столбец, который будет использоваться в качестве селектора, значение которого выводится из параметров, заданных пользователем? (это оптимизация производительности?)

2) если они разные, есть вероятность, что их обработка также отличается. Таким образом, кажется, что разделение кода выбора / обработки на отдельные блоки с последующим их вызовом по отдельности было бы для меня наиболее модульным подходом. Вы повторите часть «выберите * из», но в этом сценарии, мы надеемся, что набор таблиц будет конечным.

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

0
ответ дан 1 December 2019 в 06:16
поделиться

Вместо запроса таблиц на основе значений, введенных пользователем, вы можете выбрать процедуру. то есть
1. Создайте процедуру FOO_BAR_prc, внутри которой вы поместите запрос 'select * from foo_bar', таким образом запрос будет предварительно скомпилирован базой данных.
2. Затем на основе пользовательского ввода выполните правильную процедуру из кода вашего приложения.

Поскольку у вас около 50 таблиц, это может быть невыполнимым решением, поскольку это потребует много работы с вашей стороны.

0
ответ дан 1 December 2019 в 06:16
поделиться

Я не знаю, почему у вас данные разбросаны по нескольким таблицам, но похоже, что вы нарушаете одну из основ. Данные должны быть в таблицах, а не в виде имен таблиц.

Если таблицы имеют более или менее одинаковую структуру, подумайте, не лучше ли вместо этого поместить данные в одну таблицу. Это решит вашу проблему с динамическим запросом и сделает структуру базы данных более гибкой.

0
ответ дан 1 December 2019 в 06:16
поделиться
Другие вопросы по тегам:

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