Проверьте, существует ли таблица SQL

Параметрированный запрос И проверка ввода - это путь. Существует множество сценариев, в которых может произойти SQL-инъекция, хотя используется mysql_real_escape_string().

Эти примеры уязвимы для SQL-инъекции:

$offset = isset($_GET['o']) ? $_GET['o'] : 0;
$offset = mysql_real_escape_string($offset);
RunQuery("SELECT userid, username FROM sql_injection_test LIMIT $offset, 10");

или

$order = isset($_GET['o']) ? $_GET['o'] : 'userid';
$order = mysql_real_escape_string($order);
RunQuery("SELECT userid, username FROM sql_injection_test ORDER BY `$order`");

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

Источник : Непредвиденная инъекция SQL (при эвакуации Недостаточно)

39
задан abatishchev 19 May 2011 в 11:54
поделиться

6 ответов

bool exists;

try
{
    // ANSI SQL way.  Works in PostgreSQL, MSSQL, MySQL.  
    var cmd = new OdbcCommand(
      "select case when exists((select * from information_schema.tables where table_name = '" + tableName + "')) then 1 else 0 end");

    exists = (int)cmd.ExecuteScalar() == 1;
}
catch
{
    try
    {
        // Other RDBMS.  Graceful degradation
        exists = true;
        var cmdOthers = new OdbcCommand("select 1 from " + tableName + " where 1 = 0");
        cmdOthers.ExecuteNonQuery();
    }
    catch
    {
        exists = false;
    }
}
64
ответ дан Matt Mitchell 27 November 2019 в 02:19
поделиться

Я не думаю, что там существует один универсальный путь, который работает на все Базы данных, так как это - что-то очень определенное, которое зависит от того, как DB создается.

, Но, почему Вы хотите сделать это использование определенного запроса? Разве Вы не можете абстрагировать реализацию далеко от того, что Вы хотите сделать? Я имею в виду: почему бы не создать универсальный интерфейс, который имеет среди других, метод, названный 'TableExists (представляют имя таблицы в виде строки)', например. Затем для каждого DBMS, который Вы хотите поддерживать, Вы создаете класс, который реализует этот интерфейс, и в методе TableExists, Вы пишете определенную логику для этого DBMS.
реализация SQLServer будет тогда содержать запрос, который запрашивает sysobjects.

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

, Например:

IMyInterface foo = MyFactory.CreateMyInterface (SupportedDbms.SqlServer);

if( foo.TableExists ("mytable") )
...

я думаю, что это - то, как я должен сделать это.

10
ответ дан Frederik Gheysels 27 November 2019 в 02:19
поделиться

Если Вы пробуете за независимость базы данных, необходимо будет принять минимальный стандарт. IIRC представления ANSI INFORMATION_SCHEMA требуются для соответствия ODBC, таким образом, Вы могли запросить против них как:

select count (*) 
  from information_schema.tables 
 where table_name = 'foobar'

, Учитывая, что Вы используете ODBC, можно также использовать различный вызовы API ODBC для получения этих метаданных также.

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

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

9
ответ дан ConcernedOfTunbridgeWells 27 November 2019 в 02:19
поделиться

Я полностью поддерживаю ответ Frederik Gheysels. Если необходимо поддерживать несколько систем баз данных, необходимо реализовать код против абстрактного интерфейса с определенными реализациями система для каждой базы данных. Существует намного больше примеров несовместимого синтаксиса, чем просто проверка существующую таблицу (например: ограничение запроса к определенному числу строк).

, Но если действительно необходимо выполнить проверку с помощью обработки исключений от примера, необходимо использовать следующий запрос, который более эффективен, чем КОЛИЧЕСТВО (*), потому что база данных не имеет никакой фактической работы выбора, чтобы сделать:

SELECT 1 FROM my_table WHERE 1=2
4
ответ дан Sebastian Dietz 27 November 2019 в 02:19
поделиться

Я постарался бы не выполняться select count(x) from xxxxxx, поскольку DBMS будет на самом деле идти вперед и делать это, который может занять время для большой таблицы.

Вместо этого всего готовятся select * from mysterytable запрос. Готовить перестанет работать, если mysterytable не существует. Нет никакой потребности на самом деле выполнить подготовленный оператор.

4
ответ дан Imran Ali Khan 27 November 2019 в 02:19
поделиться

В текущем проекте на моем задании я должен записать 'агент данных', который поддерживал бы много типов БД.

, Таким образом, я решил сделать затем: запишите базовый класс с основой (независимая база данных) функциональность с помощью виртуальных методов и переопределения в подклассах все определенные для базы данных моменты

2
ответ дан abatishchev 27 November 2019 в 02:19
поделиться
Другие вопросы по тегам:

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