programing

MySQL 매개 변수화된 쿼리

shortcode 2023. 1. 8. 15:02
반응형

MySQL 매개 변수화된 쿼리

MySQLdb 모듈을 사용하여 데이터베이스에 정보를 삽입하는 데 어려움을 겪고 있습니다.테이블에 변수 6개를 삽입해야 합니다.

cursor.execute ("""
    INSERT INTO Songs (SongName, SongArtist, SongAlbum, SongGenre, SongLength, SongLocation)
    VALUES
        (var1, var2, var3, var4, var5, var6)

""")

여기 구문 좀 가르쳐 주시겠어요?

SQL 쿼리에 문자열 보간법을 사용하면 입력 매개 변수가 올바르게 빠져나오지 않고 응용 프로그램이 SQL 주입 취약성에 노출될 수 있으므로 주의해야 합니다.그 차이는 대수롭지 않게 보일지 모르지만, 실제로는 크다.

올바르지 않음(보안 문제 있음)

c.execute("SELECT * FROM foo WHERE bar = %s AND baz = %s" % (param1, param2))

정답(탈옥 포함)

c.execute("SELECT * FROM foo WHERE bar = %s AND baz = %s", (param1, param2))

되는 수식어가 DB 가 SQL을 사용하고 있는 시킵니다.printf일반적으로 사용되는 '?' 마커 대신 스타일 구문(예: 에서 사용)을 사용합니다. python-sqlite를 참조해 주세요.

몇 가지 옵션을 사용할 수 있습니다.비단뱀의 스트링 반복에 익숙해질 것입니다.미래에 이런 것을 알고 싶을 때 찾는 것이 더 성공적일 수 있는 용어입니다.

질의에 적합합니다.

some_dictionary_with_the_data = {
    'name': 'awesome song',
    'artist': 'some band',
    etc...
}
cursor.execute ("""
            INSERT INTO Songs (SongName, SongArtist, SongAlbum, SongGenre, SongLength, SongLocation)
            VALUES
                (%(name)s, %(artist)s, %(album)s, %(genre)s, %(length)s, %(location)s)

        """, some_dictionary_with_the_data)

이미 모든 데이터가 객체 또는 사전에 저장되어 있는 것을 고려하면 두 번째 형식이 더 적합합니다.또, 1년 후에 돌아와 이 메서드를 갱신할 필요가 있는 경우는, 문자열내의 「%s」의 어피아란스를 카운트 하는 것도 귀찮습니다. : )

링크된 문서에는 다음 예가 있습니다.

   cursor.execute ("""
         UPDATE animal SET name = %s
         WHERE name = %s
       """, ("snake", "turtle"))
   print "Number of rows updated: %d" % cursor.rowcount

따라서 이 코드를 자신의 코드에 맞게 조정하기만 하면 됩니다. 예:

cursor.execute ("""
            INSERT INTO Songs (SongName, SongArtist, SongAlbum, SongGenre, SongLength, SongLocation)
            VALUES
                (%s, %s, %s, %s, %s, %s)

        """, (var1, var2, var3, var4, var5, var6))

(SongLength가 숫자일 경우 %s 대신 %d를 사용해야 할 수 있습니다).

실제로 변수(SongLength)가 숫자인 경우에도 파라미터를 올바르게 바인드하려면 %s로 포맷해야 합니다.%d 를 사용하려고 하면 에러가 발생합니다.다음은 링크 http://mysql-python.sourceforge.net/MySQLdb.html에서 발췌한 내용입니다.

쿼리를 수행하려면 먼저 커서가 필요하고 커서에서 쿼리를 실행할 수 있습니다.

c=db.cursor()
max_price=5
c.execute("""SELECT spam, eggs, sausage FROM breakfast
          WHERE price < %s""", (max_price,))

이 예에서는 max_price=5 문자열에 %s을(를) 사용하는 이유는 무엇입니까?MySQLdb가 SQL 리터럴 값(문자열 '5')으로 변환하기 때문입니다.이 작업이 완료되면 쿼리는 실제로 "..."라고 표시됩니다.가격은 5인치 미만.

선택한 답변의 대안으로 Marcel과 동일한 안전한 의미론을 사용하여 Python 사전을 사용하여 값을 지정하는 간단한 방법이 있습니다.삽입할 열을 추가하거나 제거할 때 쉽게 수정할 수 있는 장점이 있습니다.

  meta_cols = ('SongName','SongArtist','SongAlbum','SongGenre')
  insert = 'insert into Songs ({0}) values ({1})'.format(
      ','.join(meta_cols), ','.join( ['%s']*len(meta_cols)))
  args = [ meta[i] for i in meta_cols ]
  cursor = db.cursor()
  cursor.execute(insert,args)
  db.commit()

여기서 meta는 삽입할 값을 저장하는 사전입니다.업데이트는 다음과 같은 방법으로 수행할 수 있습니다.

  meta_cols = ('SongName','SongArtist','SongAlbum','SongGenre')
  update='update Songs set {0} where id=%s'.
        .format(','.join([ '{0}=%s'.format(c) for c in meta_cols ]))
  args = [ meta[i] for i in meta_cols ]
  args.append(songid)
  cursor=db.cursor()
  cursor.execute(update,args)
  db.commit()

첫 번째 솔루션은 잘 작동합니다.여기에 한 가지 작은 세부사항을 추가하고 싶습니다.대체/업데이트하려는 변수가 str 유형이어야 합니다.mysql 타입은 10진수인데 쿼리를 실행하기 위해 파라미터 변수를 str로 만들어야 했습니다.

temp = "100"
myCursor.execute("UPDATE testDB.UPS SET netAmount = %s WHERE auditSysNum = '42452'",(temp,))
myCursor.execute(var)

여기 그것을 하는 다른 방법이 있다.MySQL 공식 웹사이트에 기록되어 있습니다.https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-execute.html

정신적으로는 @Trey Stout의 대답과 같은 메카닉을 사용하고 있다.하지만, 저는 이 책이 더 예쁘고 읽기 쉽다고 생각해요.

insert_stmt = (
  "INSERT INTO employees (emp_no, first_name, last_name, hire_date) "
  "VALUES (%s, %s, %s, %s)"
)
data = (2, 'Jane', 'Doe', datetime.date(2012, 3, 23))
cursor.execute(insert_stmt, data)

또한 변수의 필요성을 더 잘 설명하기 위해 다음을 수행합니다.

NB: 탈출하는 것을 주목하세요.

employee_id = 2
first_name = "Jane"
last_name = "Doe"

insert_stmt = (
  "INSERT INTO employees (emp_no, first_name, last_name, hire_date) "
  "VALUES (%s, %s, %s, %s)"
)
data = (employee_id, conn.escape_string(first_name), conn.escape_string(last_name), datetime.date(2012, 3, 23))
cursor.execute(insert_stmt, data)

언급URL : https://stackoverflow.com/questions/775296/mysql-parameterized-queries

반응형