sql >> Databáze >  >> RDS >> Sqlserver

Jak mám předat název tabulky do uloženého procesu?

Nejprve byste měli NIKDY skládání příkazů SQL v klientské aplikaci, jako je tato, to je co je SQL Injection. (Je to v pořádku pro nástroj pro správu, který nemá žádné vlastní priv, ale ne pro aplikaci pro sdílené použití).

Zadruhé, ano, parametrizované volání uložené procedury je čistší a bezpečnější.

Nicméně , protože k tomu budete muset použít Dynamic SQL, stále nechcete zahrnout předaný řetězec do textu prováděného dotazu. Místo toho chcete použít předaný řetězec k vyhledání názvů skutečných tabulky, na které by uživatel měl mít povoleno dotazovat se způsobem.

Zde je jednoduchý naivní příklad:

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

Někteří se spravedlivě ptali, proč je to bezpečnější. Doufejme, že malý Bobby Tables to dokáže objasnit:0

Odpovědi na další otázky:

  1. Samotný QUOTENAME nezaručuje bezpečnost. MS nás doporučuje, abychom to používali, ale nezaručili, že to hackeři nemohou přelstít. FYI, skutečná bezpečnost je především o zárukách. Vyhledávání v tabulce pomocí QUOTENAME je jiný příběh, je nerozbitné.

  2. QUOTENAME není pro tento příklad nezbytně nutný, obvykle postačuje samotný překlad vyhledávání na INFORMATION_SCHEMA. QUOTENAME je zde, protože je to dobrá forma zabezpečení zahrnout úplné a správné řešení. QUOTENAME zde ve skutečnosti chrání před odlišným, ale podobným potenciálním problémem známým jako latentní injekce .

Měl bych poznamenat, že totéž můžete udělat s dynamickými názvy sloupců a INFORMATION_SCHEMA.COLUMNS stůl.

Potřebu uložených procedur můžete také obejít tím, že místo toho použijete parametrizovaný dotaz SQL (viz zde:https://docs.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlcommand.parameters?view=síťový rámec-4.8). Ale myslím si, že uložené procedury poskytují lépe ovladatelné a méně náchylné bezpečnostní zařízení pro případy, jako je tento.



  1. Jak vypočítat klouzavý průměr v MySQL

  2. Automatizované testování procesu upgradu pro PostgreSQL

  3. Najděte název odkazované tabulky pomocí názvu tabulky, pole a schématu

  4. Jak získat včerejší datum v SQLite