通过PLSQL中的Java在Windows中创建文件夹
我正在尝试让我的Oracle 11g数据库在文件系统级别(Windows操作系统)创建文件夹 这是我在模式ABC_DEF上执行的代码:通过PLSQL中的Java在Windows中创建文件夹,java,function,plsql,oracle11g,directory,Java,Function,Plsql,Oracle11g,Directory,我正在尝试让我的Oracle 11g数据库在文件系统级别(Windows操作系统)创建文件夹 这是我在模式ABC_DEF上执行的代码: CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED createFolder AS public class FolderManagement { public static java.lang.String createFolder(java.lang.String folderPath) { j
CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED createFolder AS
public class FolderManagement {
public static java.lang.String createFolder(java.lang.String folderPath) {
java.lang.String folderCreated = “false”;
try {
java.io.File folder = new java.io.File(folderPath);
if(folder.exists() == true){
folderCreated = “true”; // folder already exists and is usable
}
else {
folder.mkdirs(); // If the parent folder exists, create all necessary subdirectories
if(folder.exists() == true){
folderCreated = “true”;
}
}
}
catch(Exception e){
folderCreated = “false. Error message [” + e.getMessage() + “]”;
}
return folderCreated;
}
};
/
CREATE OR REPLACE FUNCTION createFolder(folderPath IN VARCHAR2) RETURN VARCHAR2 AS LANGUAGE JAVA NAME ‘FolderManagement.createFolder(java.lang.String) return java.lang.String’;
/
然后,我有一个Oracle软件包,如下所示:
CREATE OR REPLACE PACKAGE ABC_DEF.FILE_UTILITIES AS
parentFolder CONSTANT VARCHAR2(4000) := ‘H:\Oracle logs’;
FUNCTION createDirectory(fullPathToFolder IN VARCHAR2) RETURN BOOLEAN;
END;
/
CREATE OR REPLACE PACKAGE BODY ABC_DEF.FILE_UTILITIES AS
FUNCTION createDirectory(fullPathToFolder IN VARCHAR2) RETURN BOOLEAN IS
folderCreated BOOLEAN := FALSE;
returnedValue VARCHAR2(4000);
BEGIN
SELECT createFolder(fullPathToFolder)
INTO returnedValue
FROM DUAL;
DBMS_OUTPUT.PUT_LINE(‘Returned value from folder creation is [’ || returnedValue || ‘]’);
IF UPPER(returnedValue) = ‘TRUE’ THEN
folderCreated := TRUE;
END IF;
RETURN folderCreated;
EXCEPTION
WHEN OTHERS THEN
folderCreated := FALSE;
RETURN folderCreated;
END;
END;
/
现在,在我的SYS(具有SYSDBA权限)模式上,我已经执行了下面的命令,该命令应该授予ABC_DEF模式读取/写入/删除文件夹“H:\Oracle logs”的任何递归级别的文件和文件夹的权限
BEGIN
DBMS_JAVA.GRANT_PERMSSION(
grantee => ‘ABC_DEF’,
permission_type => ‘SYS:java.io.FilePermission’,
permission_name => ABC_DEF.FILE_UTILITIES.parentFolder || ‘\-’, —- Should grant recursive permissions to any subfolder and any file located in any subfolder
permission_action => ‘read,write,delete’
);
END;
/
回到我的ABC_DEF模式,当我尝试执行以下代码时,我从Java代码中得到一个异常:
DECLARE
subfolderToCreate VARCHAR2(4000) := ‘\2019\November’;
folderWasCreated BOOLEAN := FALSE;
fullFolderPath VARCHAR2(4000);
BEGIN
fullFolderPath := FILE_UTILITIES.parentFolder || subfolderToCreate;
folderWasCreated := FILE_UTILITIES.createDirectory(fullFolderPath);
IF folderWasCreated = TRUE THEN
DBMS_OUTPUT.PUT_LINE(‘Folder was created.’);
ELSE
DBMS_OUTPUT.PUT_LINE(‘Folder was not created.’);
END IF;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(‘Folder wasn’’t created. Exception message [’ || SQLERRM || ‘]’);
END;
我得到以下错误:
Permission (java.io.FilePermission H:\Oracle logs\2019\November read) has not been granted to ABC_DEF. The PL/SQL to grant this is dbms_java.grant_permission(‘ABC_DEF’, ‘SYS:java.io.FilePermission’, ‘H:\Oracle logs\2019\November’, ‘read’)
如果使用父文件夹(已存在于文件系统级别),则会出现相同的错误
关于为什么以及如何解决这个问题,有什么想法吗
编辑:根据请求添加信息
询问
SELECT *
FROM DBA_JAVA_POLICY
WHERE GRANTEE = ‘ABC_DEF’AND TYPE_NAME LIKE ‘%File%’;
显示“名称”列下文件夹“H:\Oracle日志\-”的一行,该行已为“读、写、删除”操作启用
至于H:drive,它是一个物理驱动器,而不是一个网络驱动器
关于Windows级别的文件夹设置,“Oracle logs”文件夹在Windows级别已经存在,并且“Everyone”的访问权限完全由“Everyone”控制。我已解决此问题,如下所示:
- 我以SYS的身份运行此命令,从Oracle端删除了权限:
DECLARE permissionNumber NUMBER(35); BEGIN SELECT SEQ INTO permissionNumber FROM DBA_JAVA_POLICY WHERE TYPE_NAME LIKE ‘%File%’ AND GRANTEE = ‘ABC_DEF’; DBMS_JAVA.disable_permission(permissionNumber); DBMS_JAVA.delete_permission(permissionNumber); END; /
BEGIN
DBMS_JAVA.GRANT_PERMISSION(
GRANTEE => ‘ABC_DEF’,
PERMISSION_TYPE => ‘java.io.FilePermission’
PERMISSION_NAME => ABC_DEF.FILE_UTILITIES.parentFolder || ‘\-’,
PERMISSION_ACTION => ‘execute’
);
END;
/
BEGIN
DBMS_JAVA.GRANT_PERMISSION(
GRANTEE => ‘ABC_DEF’,
PERMISSION_TYPE => ‘java.io.FilePermission’
PERMISSION_NAME => ABC_DEF.FILE_UTILITIES.parentFolder || ‘\-’,
PERMISSION_ACTION => ‘write’
);
END;
/
BEGIN
DBMS_JAVA.GRANT_PERMISSION(
GRANTEE => ‘ABC_DEF’,
PERMISSION_TYPE => ‘java.io.FilePermission’
PERMISSION_NAME => ABC_DEF.FILE_UTILITIES.parentFolder || ‘\-’,
PERMISSION_ACTION => ‘read’
);
END;
/
然后,我在Windows上的文件系统级别执行了相同的操作:从文件夹设置中删除权限并重新添加
最后,我重新运行了给我一个异常的代码。它成功了。仍然有一种情况是假阴性的,在这种情况下会引发异常,即如果subFolderToCreate变量为空
我还注意到,由于某种原因,它没有立即起作用。它需要几分钟才能工作…这里有很多无关的信息。错误消息似乎准确地告诉您需要做什么。问:在执行“DBMS_JAVA.GRANT_permission”之后,您是否查看了“ABC_DEF”的权限?您是否看到错误消息“已授予”中提到的所有权限?问:“ABC_DEF”映射到的windows用户如何?问:“H:”是网络共享吗?如果是这样,“ABC_DEF”是否具有windows域权限来读/写这些目录?我为您的问题添加了答案。不过我不同意这些无关的信息。我添加了java部分和调用它的存储过程的详细信息,以防我弄乱了该部分。我想彻底检查一下。