PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

Postgresql:डेटाबेस ट्रिगर में सिंगल कोट्स से कैसे बचें?

सामान्य एकल में, उद्धरण उन्हें दोगुना करके बच जाते हैं।

अपने वेरिएबल्स को SQL स्ट्रिंग में जोड़ने के लिए, आपको quote_literal() . का उपयोग करना चाहिए - वह फ़ंक्शन एकल उद्धरण से ठीक से बचने का ख्याल रखता है, जैसे:

quote_literal(temp_row.row_data)

ऐसा कहने के बाद:बेहतर (और सुरक्षित) समाधान format() . के साथ संयुक्त पैरामीटर का उपयोग करना है :

EXECUTE 
   format('INSERT INTO audit.%I_history values ($1, $2, $3)', tg_table_name)
   using temp_row.action_tstamp_tx, temp_row.action, temp_row.row_data; 

%I प्लेसहोल्डर आमतौर पर पहचानकर्ता से ठीक से बचने का ख्याल रखता है, हालांकि इस मामले में यह काम नहीं करेगा। यदि आप 100% सुनिश्चित होना चाहते हैं कि गैर-मानक तालिका नाम भी ठीक से काम करते हैं, तो आपको पहले लक्ष्य तालिका नाम को एक चर में रखना होगा और उसका उपयोग format() के लिए करना होगा। समारोह:

l_tablename := TG_TABLE_NAME || '_history';
EXECUTE 
   format('INSERT INTO audit.%I_history values ($1, $2, $3)', l_tablename)
   using ....

यह हिस्सा:

v_sql = 'select * from ' || TG_TABLE_NAME::regclass || '_history';
execute v_sql into temp_row;

पहली पंक्ति के बाद भी विफल होने जा रहा है। execute .. into ... क्वेरी को एकल . लौटाने की अपेक्षा करता है . आप जिस कथन का उपयोग कर रहे हैं वह सभी लौटाएगा इतिहास तालिका से पंक्तियाँ।

मुझे यह भी समझ में नहीं आता कि आप पहली बार ऐसा क्यों करते हैं।

आपको इतिहास तालिका से बिल्कुल भी चयन करने की आवश्यकता नहीं है।

ऐसा कुछ पर्याप्त होना चाहिए (अप्रयुक्त! ):

IF (TG_OP = 'UPDATE' AND TG_LEVEL = 'ROW') THEN
    temp_row := OLD;
ELSIF (TG_OP = 'DELETE' AND TG_LEVEL = 'ROW') THEN
    temp_row := OLD;
ELSIF (TG_OP = 'INSERT' AND TG_LEVEL = 'ROW') THEN
    temp_row := NEW;
ELSE
    RAISE EXCEPTION '[audit.if_modified] - Trigger func added as trigger for unhandled case: %, %',TG_OP, TG_LEVEL;
    RETURN NULL;
END IF;

execute format ('insert ... values ($1, $2, $3') 
   using now(), SUBSTRING(TG_OP,1,1), temp_row;

अंत में:ऑडिट ट्रिगर पहले भी लिखे जा चुके हैं, और इसके लिए बहुत सारे तैयार समाधान हैं:




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. तैयार बयानों के लिए अशक्त बाध्य करते समय बाइटा त्रुटि पोस्टग्रेज करता है

  2. Npgsql 12 और ef 6 का एक साथ उपयोग करना - क्या कोई इसके साथ सफल हुआ है?

  3. HQL - जांचें कि क्या किसी सरणी में कोई मान है

  4. java.sql.SQLException:कनेक्शन पहले ही बंद कर दिया गया है

  5. कुप्पी-sqlalchemy के साथ स्वत:वृद्धिशील प्राथमिक कुंजी बनाने में असमर्थ