복붙노트

[SQL] 어떻게 저장된 프로 시저에 테이블 이름을 통과해야합니까?

SQL

어떻게 저장된 프로 시저에 테이블 이름을 통과해야합니까?

난 그냥 거대한 SQL 문을 복용 우리의 사이트에 대한 몇 가지 코드로 SQL 서버에 전달 후 약간의 검색을 수행하고 일부 사용자 값을 기준으로 대체 의해 코드에서 수정이 ... 이상한 일에 달렸다 쿼리.

나는 이것이 매개 변수로 사용자 값으로, 저장된 시저에 매개 변수가있는 쿼리로 청소기 될 것이라고 생각했다,하지만 난 더 밀접하게 보았을 때 나는 그들이 그 일을 할 수있는 이유는 ... 테이블들은 IS에서 선택하는 것을 볼 수 이러한 사용자의 값에 따라 가변적.

예를 들어, 하나의 경우에 값은 "FOO_BAR SELECT * FROM"( "FOO", "BAR") 같은 것을 끝낼 것이다 쿼리를한다면

이 작업을 수행 할 수있는 쉽고 명확한 방법이 있나요? 내가 노력하고있어 모든 우아 보인다.

편집 : 나는, 물론, 동적 저장된 프로 시저에서 SQL을 생성하고,이 (bleh)를 실행,하지만 난 아무것도 얻은 한 경우 그 시점에서 내가 궁금하네요 수 있습니다.

EDIT2 : 새 열이 여러 사람이 직접 지적하거나 언급 한이 모든 것을 해결하는 좋은 방법이 될 것 같은 다른 이름으로 하나 개의 테이블에 그들 모두를 가지고, 어떤 지능적인 방법으로 테이블 이름을 말 리팩토링. 슬프게도,이 경우 옵션을 선택하지 않습니다.

해결법

  1. ==============================

    1.우선, 당신은 무엇 SQL 주입이라고,이 같은 클라이언트 응용 프로그램에서 SQL 명령 조성하지 않을 것이다. (자신의 더 privs 및이없는 관리 도구에 대한 확인 있지만 공유 사용 응용 프로그램).

    우선, 당신은 무엇 SQL 주입이라고,이 같은 클라이언트 응용 프로그램에서 SQL 명령 조성하지 않을 것이다. (자신의 더 privs 및이없는 관리 도구에 대한 확인 있지만 공유 사용 응용 프로그램).

    둘째, 그래, 저장 프로 시저에 대한 매개 변수화 호출은 깨끗하고 안전한 모두이다.

    이 작업을 수행하는 동적 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
    

    이 안전한 이유 일부는 상당히 요구했다. 바라 건데, 작은 바비 테이블이 명확를 할 수 있습니다 : 0

    더 많은 질문에 대한 답변 :

    나는 당신이 동적 열 이름과 INFORMATION_SCHEMA.COLUMNS 테이블과 같은 일을 할 수 있음을 유의하십시오.

    https://docs.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlcommand.parameters?view= : 당신은 대신 매개 변수가있는 SQL 쿼리를 사용하여 저장 프로 시저에 대한 필요성 바이 패스 (여기에서 볼 수 있습니다 netframework-4.8). 하지만 저장 프로 시저가 이런 경우에 대한 더 관리하고 덜 오류가 발생하기 쉬운 보안 기능을 제공한다고 생각합니다.

  2. ==============================

    2.(유엔) 다행히이 일을있는 방법은 없습니다 - 당신은 동적 SQL 생성 이외의 저장 코드에 매개 변수로 전달 테이블 이름을 사용할 수 없습니다. 이 곳은 SQL 코드를 생성하는 결정에 올 때, 내가 응용 프로그램 코드가 아니라 그 저장 코드를 선호합니다. 응용 프로그램 코드는 일반적으로 빠르고 유지 보수가 용이하다.

    (유엔) 다행히이 일을있는 방법은 없습니다 - 당신은 동적 SQL 생성 이외의 저장 코드에 매개 변수로 전달 테이블 이름을 사용할 수 없습니다. 이 곳은 SQL 코드를 생성하는 결정에 올 때, 내가 응용 프로그램 코드가 아니라 그 저장 코드를 선호합니다. 응용 프로그램 코드는 일반적으로 빠르고 유지 보수가 용이하다.

    작업중인 솔루션처럼, 나는 더 깊은 재 설계를 건의 할 것없는 경우에 당신이 (당신이 더 이상 매개 변수 어디서나 같은 테이블 이름을 통과해야하므로 즉 스키마 / 애플리케이션 로직을 변경하지).

  3. ==============================

    3.나는 동적으로 저장된 프로 시저에서 SQL을 생성에 대해 주장 할 것이다; 그 문제에 당신을 얻을 것이다 및 주입 취약점이 발생할 수 있습니다.

    나는 동적으로 저장된 프로 시저에서 SQL을 생성에 대해 주장 할 것이다; 그 문제에 당신을 얻을 것이다 및 주입 취약점이 발생할 수 있습니다.

    대신, 쿼리에 의해 영향을받을 수있는 모든 테이블을 분석하고 쿼리에 사용할 테이블을 결정하는 것 열거의 일종을 만들 것입니다.

  4. ==============================

    4.당신 같은 소리는 ORM 솔루션을 더 나을 것입니다.

    당신 같은 소리는 ORM 솔루션을 더 나을 것입니다.

    내가 저장 프로 시저에서 동적 SQL을 볼 때 나는 싫증이 나다.

  5. ==============================

    5.당신이 고려할 수있는 한 가지는 당신이 원하는 동일한 SQL 명령이 포함 된 경우 문을 만드는 것입니다, 유효한 각 테이블에 대해 한 번,이 절차에 문자열로 테이블 이름을 전달하고 경우에 실행하는 명령을 선택합니다.

    당신이 고려할 수있는 한 가지는 당신이 원하는 동일한 SQL 명령이 포함 된 경우 문을 만드는 것입니다, 유효한 각 테이블에 대해 한 번,이 절차에 문자열로 테이블 이름을 전달하고 경우에 실행하는 명령을 선택합니다.

    을 알려주는 위의 제안이 있는지 확인하기 위해 시스템 테이블에서 선택하는 보안 사람으로 그런데 유효한 테이블이 나에게 낭비 작업처럼 보인다 있습니다. 누군가가 QUOTENAME을 통과 삽입 할 수있는 경우 () 다음 다음 주입 시스템 테이블에 단지뿐만 아니라 기본 테이블에서 작동합니다. 이 함께 할 수있는 유일한 방법은 유효한 테이블 이름을 보장하기 위해, 그리고 당신이 전혀 QUOTENAME ()를 사용하지 않기 때문에 제안은 위의 것과 더 나은 방법이라고 생각합니다.

  6. ==============================

    6.해당 테이블의 열 세트가 동일하거나 다르게인지에 따라, 나는 장기적으로 두 가지 방법으로 접근하는 것입니다 :

    해당 테이블의 열 세트가 동일하거나 다르게인지에 따라, 나는 장기적으로 두 가지 방법으로 접근하는 것입니다 :

    1) 만약 그들이 동일한 이유 값이 사용자 제공 파라미터들로부터 도출 된 선택기로서 사용되는 새로운 컬럼을 생성하지? (그것은 성능 최적화입니까?)

    그들이 다른 경우 2), 기회는 그것들을 처리하는 것도 다른 점이다. 따라서, 그것은 분할과 같은 별도의 블록으로 선택 / 핸들 코드를 보인다 후 개별적으로 호출하면 나에게 가장 모듈 형 접근 방식이 될 것입니다. 당신은, 부분 "에서 선택 *"를 반복합니다 그러나이 시나리오에서 테이블 세트 희망 유한하다.

    호출 코드가 테이블 이름의 임의의 두 부품을 공급 할 수 있도록 허용하는 것은 매우 위험 Feel로에서 선택을 할 수 있습니다.

  7. ==============================

    7.난 당신이 여러 테이블을 통해 데이터 확산이 이유를 모르겠지만, 당신은 기본 중 하나를 깨고있다처럼 소리가 난다. 데이터는 테이블이 아닌 테이블의 이름으로해야한다.

    난 당신이 여러 테이블을 통해 데이터 확산이 이유를 모르겠지만, 당신은 기본 중 하나를 깨고있다처럼 소리가 난다. 데이터는 테이블이 아닌 테이블의 이름으로해야한다.

    테이블이 더 많거나 적은 동일한 레이아웃이있는 경우, 대신 하나의 테이블에 데이터를 입력하는 가장 좋은 것입니다 경우에 고려한다. 즉, 동적 쿼리를 사용하여 문제를 해결할 것, 그리고보다 유연한 데이터베이스 레이아웃을 만들 것입니다.

  8. ==============================

    8.대신 사용자 입력 값에 따라 테이블을 쿼리의 대신 절차를 선택할 수 있습니다. 즉 말하자면     절차 FOO_BAR_prc 및 쿼리를 넣어 내부를 만들기 1. 쿼리는 데이터베이스에서 미리 컴파일됩니다 그런 식으로, 'foo_bar SELECT * FROM'.     2.이 그런 다음 사용자 입력을 기반으로 이제 응용 프로그램 코드에서 올바른 절차를 실행합니다.

    대신 사용자 입력 값에 따라 테이블을 쿼리의 대신 절차를 선택할 수 있습니다. 즉 말하자면     절차 FOO_BAR_prc 및 쿼리를 넣어 내부를 만들기 1. 쿼리는 데이터베이스에서 미리 컴파일됩니다 그런 식으로, 'foo_bar SELECT * FROM'.     2.이 그런 다음 사용자 입력을 기반으로 이제 응용 프로그램 코드에서 올바른 절차를 실행합니다.

    당신이 주변에 50 테이블을 가지고 있기 때문에,이 힘은 당신의 부분에 많은 작업을 필요로하지만 실현 가능한 해결책이 될 수 없습니다.

  9. ==============================

    9.사실, 저장 프로 시저에서 테이블을 만들 테이블 이름을 전달하는 방법을 알고 싶어. 이름을 매개 변수로 전달과 함께 몇 가지 답변을 읽고 내 말에 약간의 수정을 시도, 나는 마침내 수 테이블을 만들 수 있습니다. 여기에 다른 사람이 그것에서 오류를 확인하기위한 저장 프로 시저입니다.

    사실, 저장 프로 시저에서 테이블을 만들 테이블 이름을 전달하는 방법을 알고 싶어. 이름을 매개 변수로 전달과 함께 몇 가지 답변을 읽고 내 말에 약간의 수정을 시도, 나는 마침내 수 테이블을 만들 수 있습니다. 여기에 다른 사람이 그것에서 오류를 확인하기위한 저장 프로 시저입니다.

    USE [데이터베이스 이름] 가다 / ****** 대상 :.의 StoredProcedure [DBO] [sp_CreateDynamicTable] 스크립트 날짜 : 2015년 6월 20일 16시 56분 25초 ****** / SET ANSI_NULLS ON 가다 SET QUOTED_IDENTIFIER ON 가다 CREATE PROCEDURE [DBO]. sp_CreateDynamicTable]     @tName의 VARCHAR (255) 같이 BEGIN     SET NOCOUNT ON;     DECLARE의 @SQL의 NVARCHAR (최대)

    SET @SQL = N'CREATE TABLE [DBO].['+ @tName + '] (DocID nvarchar(10) null);'
    
        EXECUTE sp_executesql @SQL
    

    종료

  10. ==============================

    10.@RBarry 젊은 당신은 이미 INFORMATION_SCHEMA.TABLES에서 쿼리의 결과에 포함되기 때문에 쿼리 문자열에 @ActualTableName에 괄호를 추가 할 필요가 없습니다. 실행될 때 그렇지 않으면, 오류 (들)이있을 것이다.

    @RBarry 젊은 당신은 이미 INFORMATION_SCHEMA.TABLES에서 쿼리의 결과에 포함되기 때문에 쿼리 문자열에 @ActualTableName에 괄호를 추가 할 필요가 없습니다. 실행될 때 그렇지 않으면, 오류 (들)이있을 것이다.

    AS PROC spCountAnyTableRows (NVARCHAR (255)와 같은 @PassedTableName) 만들기 - 안전하게 비 시스템 테이블에서 행의 카운트 수 BEGIN     @ActualTableName NVARCHAR AS (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 + '];'
    
    -- changed to this
    SELECT @sql = 'SELECT COUNT(*) FROM ' + @ActualTableName + ';'
    
    EXEC(@SQL)
    

    종료

  11. from https://stackoverflow.com/questions/1246760/how-should-i-pass-a-table-name-into-a-stored-proc by cc-by-sa and MIT license