Борис Макушкин
Alba Spectrum Technologies
(095) 918-3314, (095) 918-3111, help@albaspectrum.com
Два мира, две идеологии, два непримиримых соперника – как еще можно точнее описать два столпа RDBMS мира – Oracle Database и MS SQL Server. Горы TPC тестов, доказывающих превосходство поочередно то одной, то другой стороны. Легионы приверженцев одного и другого продукта, яростно доказывающие достоинства и не принимающие никаких аргументов, свидетельствующих о недостатках своего любимца. Инь и янь рынка SQL серверов… Возможно ли ужиться вместе двум столько разным сущностям? Еще как! И задача нашего цикла статей дать Вам некоторые подсказки по обеспечению прозрачного переноса данных между этими двумя вселенными.
Целью сегодняшней статьи является демонстрация возможностей Oracle по использованию первичных и вторичных ключей в стиле MS SQL (Guid datatype). Отличительной особенностью Oracle является свободное использование встроенной java машины – с ее помощью можно писать хранимые процедуры сколь угодно высокой сложности. Этим мы и воспользуемся в нашей работе. Итак приступим:
package com.albaspectrum.util;
import java.security.*;
import java.util.*;
import java.io.*;
import java.net.*;
import java.rmi.server.*;
public class Guid {
private String internalGuid = null;
public String newGuid() throws Exception {
setGuid(generateGuid());
return getGuid();
}
public String getGuid() {
return internalGuid;
}
public void setGuid(String assignedGuid) {
internalGuid = assignedGuid;
}
public String generateGuid() throws Exception {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
PrintStream printStream = new PrintStream(outputStream);
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
messageDigest.update(getSourceMessage());
byte[] byteDigest = messageDigest.digest();
if (byteDigest != null) {
for(int i = 0; i < byteDigest.length; i++)
hexDigit(printStream, byteDigest[i]);
} else {
throw new Exception("Got broken GUID");
}
return (outputStream.toString());
}
private static void hexDigit(PrintStream p, byte x) {
char c;
c = (char) ((x >> 4) & 0xf);
if (c > 9) {
c = (char) ((c - 10) + 'a');
} else {
c = (char) (c + '0');
}
p.write(c);
c = (char) (x & 0xf);
if (c > 9) {
c = (char)((c - 10) + 'a');
} else {
c = (char)(c + '0');
}
p.write(c);
}
protected byte[] getSourceMessage() throws Exception {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
PrintStream printStream = new PrintStream(outputStream);
printStream.print(getSourceString());
return outputStream.toByteArray();
}
protected String getSourceString() throws Exception {
StringBuffer resultString = new StringBuffer(InetAddress.getLocalHost().toString());
resultString.append("; ").append(new Date().toString());
resultString.append("; ").append(new Integer(new Random().nextInt()).toString());
resultString.append("; ").append(new Integer(new Random().nextInt()).toString());
resultString.append("; ").append(new Integer(new Random().nextInt()).toString());
resultString.append("; ").append(new Integer(new Random().nextInt()).toString());
resultString.append("; ").append(new UID().toString());
return resultString.toString();
}
public static String getMsStyleGuid(String guid) {
String formattedGuid = "{" + guid.substring(0, 8) + "-" + guid.substring(8, 12) + "-" +
guid.substring(12, 16) + "-" + guid.substring(16, 20) + "-" + guid.substring(20, 32) + "}";
return formattedGuid;
}
public static String getGuidForOracle() throws Exception {
Guid guid = new Guid();
String rawGuid = guid.newGuid();
return getMsStyleGuid(rawGuid);
}
}
package com.albaspectrum.util;
public class TestGuid {
public static void main(String args[]) throws Exception {
Guid guid = new Guid();
String rawGuid = guid.newGuid();
System.out.println("Generated GUID: " + rawGuid);
System.out.println("Generated MS-style GUID: " + Guid.getMsStyleGuid(rawGuid));
}
}
oracle@vega:~/product/10gR1/bin> loadjava -u system/manager -v -resolve /tmp/Guid.java
arguments: '-u' 'system/manager' '-v' '-resolve' '/tmp/Guid.java'
creating : source com/albaspectrum/util/Guid
loading : source com/albaspectrum/util/Guid
created : CREATE$JAVA$LOB$TABLE
resolving: source com/albaspectrum/util/Guid
oracle@vega:~/product/10gR1/bin>
SELECT * FROM user_objects WHERE object_type LIKE ‘JAVA%’
Обратим особое внимание на поля OBJECT_NAME и STATUS
create or replace function GET_GUID
RETURN VARCHAR2
AS LANGUAGE JAVA
NAME 'com.albaspectrum.util.Guid.getGuidForOracle() return String';
SET SERVEROUTPUT ON
VARIABLE guid VARCHAR2(38);
CALL GET_GUID() INTO :guid;
PRINT guid
Борис Макушкин – ведущий девелопер в Alba Spectrum Technologies – компании – партнере Oracle и Microsoft Business Solutions в городах Москва, Петербург, Екатеринбург, Казань, Ростов и обслуживающей всю Российскую Федерацию (www.albaspectrum.com), Борис является Microsoft CRM SDK, C#, VB.Net, SQL, Oracle, Unix девелопером.

