- Реализация на PL/SQL:
-
SHA-1:
CREATE OR REPLACE FUNCTION SHA1(plain_text VARCHAR2) RETURN VARCHAR2 AS BEGIN RETURN UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(DBMS_CRYPTO.HASH (src => utl_i18n.string_to_raw (plain_text, 'AL32UTF8'), typ => DBMS_CRYPTO.HASH_SH1))); END;
- MD5:
CREATE OR REPLACE FUNCTION MD5(plain_text VARCHAR2) RETURN VARCHAR2 IS BEGIN RETURN RAWTOHEX(DBMS_OBFUSCATION_TOOLKIT.MD5(INPUT => TL_RAW.CAST_TO_RAW(plain_text) )); END;
-
SHA-1:
- Реализация на Java:
import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class CryptoUtils { private final static char[] ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray(); public static String sha1(String plain) { try { MessageDigest md = MessageDigest.getInstance("sha"); md.update(plain.getBytes()); byte[] digest = md.digest(); return encode(digest); /* Альтернативные варианты: return javax.xml.bind.DatatypeConverter.printBase64Binary(digest); или return com.sun.org.apache.xml.internal.security.utils.Base64.encode(digest); */ } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return null; } } public static String md5(String raw) { try { MessageDigest md = MessageDigest.getInstance("MD5"); md.update(raw.getBytes(), 0, raw.length()); return new BigInteger(1, md.digest()).toString(16); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return null; } } public static String encode(byte[] buf) { int size = buf.length; char[] ar = new char[((size + 2) / 3) * 4]; int a = 0; int i = 0; while (i < size) { byte b0 = buf[i++]; byte b1 = (i < size) ? buf[i++] : 0; byte b2 = (i < size) ? buf[i++] : 0; int mask = 0x3F; ar[a++] = ALPHABET[(b0 >> 2) & mask]; ar[a++] = ALPHABET[((b0 << 4) | ((b1 & 0xFF) >> 4)) & mask]; ar[a++] = ALPHABET[((b1 << 2) | ((b2 & 0xFF) >> 6)) & mask]; ar[a++] = ALPHABET[b2 & mask]; } switch (size % 3) { case 1: ar[--a] = '='; case 2: ar[--a] = '='; } return new String(ar); } }
Показаны сообщения с ярлыком pl/sql. Показать все сообщения
Показаны сообщения с ярлыком pl/sql. Показать все сообщения
суббота, 15 сентября 2012 г.
Хеширование SHA-1 и MD5 на PL/SQL и Java
пятница, 10 апреля 2009 г.
Автономные транзакции
Обработка транзакций - главная обязанность программного механизма любой базы данных, и Oracle здесь не является исключением. Чтобы понять суть дела, давайте определим, что составляет транзакцию. В Oracle транзакция - это логическая единица работы, выполняемая между точками commit/rollback (фиксация/откат) одним или более SQL- (или PL/SQL-) предложениями. Это означает, что в программе, которая явно содержит предложение commit или rollback, все измененные в текущей транзакции данные будут или зафиксированы (commit) в базе, или будет произведен откат (rollback), и все изменения будут отменены.
Это может представить проблему при обработке ошибок, как проиллюстрировано ниже:
Автономная транзакция может разрешить эту проблему.
Автономная транзакция отделяется от начальной транзакции, создавая, тем самым, возможность для прикладной программы независимо фиксировать/откатывать (commit/rollback) свои транзакции.
Автономные транзакции должны быть объявлены с использованием фразы
PRAGMA AUTONOMOUS_TRANSACTION в PL/SQL-программе. Вот как выглядит декларация подпрограммы (routine), обрабатывающей ошибку:
Вот пример, как мы можем "переделать" ("retool") подпрограмму p_update_employee:
Источник: Oracle Professional eXTRA #2.9, eNewsletter Autonomous Transactions
Это может представить проблему при обработке ошибок, как проиллюстрировано ниже:
CREATE OR REPLACE PROCEDURE p_update_employee
IS
BEGIN
-- ...
-- логика приложения
--
COMMIT;
--
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
INSERT INTO error_logs VALUES (20101, sqlerrm);
COMMIT;
END;
/
В процедуре p_update_employee обращение к фразе WHEN OTHERS производится по любой ошибке Оracle. Цель - записать сообщение об ошибке в таблицу приложения, названную здесь error_logs. Поскольку мы хотим выделить ошибки, обнаруженные логикой приложения с указанием породивших их проблем, нам надо выполнить явный откат до задействования предложения INSERT, чтобы только затем последующий commit зафиксирует сообщение об ошибке. Такая реализация представляется несколько неуклюжей, поскольку программа реально включает в себя два процессных трека - логику приложения и регистрацию ошибок.Автономная транзакция может разрешить эту проблему.
Автономная транзакция отделяется от начальной транзакции, создавая, тем самым, возможность для прикладной программы независимо фиксировать/откатывать (commit/rollback) свои транзакции.
Автономные транзакции должны быть объявлены с использованием фразы
PRAGMA AUTONOMOUS_TRANSACTION в PL/SQL-программе. Вот как выглядит декларация подпрограммы (routine), обрабатывающей ошибку:
CREATE OR REPLACE PROCEDURE p_error(
i_error IN NUMBER,
i_text IN VARCHAR2)
IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO error_logs (error_code, error_text)
VALUES (i_error, i_text);
--
COMMIT;
--
END;
/
Теперь процедура p_error работает независимо от вызываемой во время выполнения этой подпрограммы.Вот пример, как мы можем "переделать" ("retool") подпрограмму p_update_employee:
CREATE OR REPLACE PROCEDURE p_update_employee
IS
lx_test EXCEPTION;
BEGIN
-- ...
-- Логика приложения
--
RAISE lx_test;
--
COMMIT;
--
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
p_error(20101, sqlerrm);
END;
/
Заметим, что в секции EXCEPTION фраза WHEN OTHERS вызывает откат (rollback) данных, измененных приложением, тогда как подпрограмма p_error вызывает фиксацию (commit) только, чтобы сохранить последнюю вставленную запись в журнал ошибок (error log). Источник: Oracle Professional eXTRA #2.9, eNewsletter Autonomous Transactions
Количество изменённых записей
Пример процедуры:
Вывод:
BEGIN
UPDATE emp e SET e.mgr=7698 WHERE e.job='SALESMAN';
dbms_output.put_line(sql%rowcount||' ROWS UPDATED');
END;
Вывод:
set serveroutput on
4 ROWS UPDATED
Подписаться на:
Сообщения (Atom)