如何将PL/SQL输出(clob)保存为XML文件
本文关键字:clob 保存 文件 XML 输出 PL SQL | 更新日期: 2023-09-27 18:03:48
在这个阶段,我觉得自己很愚蠢,因为这似乎不是我应该做的任务,但在睡了一会儿之后,我的脑海里闪过了1000个想法,我觉得我现在是锅里的青蛙,隧道视觉病毒笼罩着解决方案。是:
我有一个PL/SQL查询,使用DBMS_XMLGEN.getxml从几个表中选择数据为XML格式(1行,1列是CLOB类型)。
我的问题是将这个XML输出返回到c#,并询问用户他想将这个输出保存为output. XML文件,在他的个人pc上。
我使用ASP.net与JQuery (AJAX),因此张贴到.aspx页面时,点击链接,并使用返回的数据(xml来自这个实例中的查询)来保存。使用OLEDB命令与OLEDB数据读取器似乎不是正确的方法…
做这件事的最好方法是什么?我没有在。net中进行过很多序列化工作,但我认为这是最好的方法(根据我所做的研究)?有人能举个例子说明我的情况吗?
我的想法基本上是在内存中创建这个输出/文件,询问用户想要保存它的位置,将其保存为.xml文件并清除内存。
更新:好的,我设法创建了一个XMLDocument,它很容易从我的查询中接受xml输出。我怎样才能从用户那里得到关于在他的电脑上保存这个文件的输入?
我的代码:
Javascript:
function XML_ExportAppRestrictions() {
try {
var data = {"action": "exportAppRestrictions"};
var returned = AjaxLoad('Modules/Common/Common.aspx', null, data, null, null, false);
if (returned.toString().toUpperCase().substring(0, 5) == "ERROR") {
return;
}
else {
// should the file be saved here or in my aspx page using xmldoc.save?
// Using xmldoc.save will only be able to save the file on the server yes?
}
}
catch (ex) {
alert(ex.Message);
}
}
ASP: if (Request["action"] == "exportAppRestrictions")
{
// Create and open DB connection
conn.ConnectionString = SG_Common.CommonClass.NetRegUDL;
common.OpenDBConnection(ref conn);
// Create command and set SQL statement
cmd.Connection = conn;
cmd.CommandType = System.Data.CommandType.Text;
// select text was removed below due to it's length
cmd.CommandText = "select x as AppRestrictions from dual";
rd = cmd.ExecuteReader();
if (rd.HasRows)
{
if (rd.Read())
{
str = rd["AppRestrictions"].ToString();
}
}
rd.Close();
System.Xml.XmlDocument xmldoc = new System.Xml.XmlDocument();
xmldoc.InnerXml = str;
xmldoc.Save("c:''xmltest.xml");
goto Done;
}
// Done runs in a seperate try/catch statement and only returns data to the calling js function.
Done:
Response.Write(str);
XML应该只是UTF8明文。我已经对对象使用了序列化。也许有人会纠正我,但我没有发现有必要对纯文本或二进制数据使用序列化。
为了使这些数据通过内存,这里有一个很好的StackOverflow答案,展示了如何使用MemoryStream和字节缓冲区。
因为如果你可以把它放入byte[]缓冲区,你可以这样做:
public bool SaveDocument( Byte[] docbinaryarray, string docname)
{
string strdocPath;
strdocPath = "C:''DocumentDirectory''" + docname;
FileStream objfilestream =new FileStream(strdocPath,FileMode.Create,FileAccess.ReadWrite);
objfilestream.Write(docbinaryarray,0,docbinaryarray.Length);
objfilestream.Close();
return true;
}
有关系统的更多信息,请参阅此处。IO方法,例如:
StreamWriter writer = new StreamWriter("c:''KBTest.txt");
writer.WriteLine("File created using StreamWriter class.");
writer.Close();
this.listbox1.Items.Clear();
addListItem("File Written to C:''KBTest.txt");
UPDATE 1 (Windows):
(我以为你在找System.Windows.Forms.SaveFileDialog)
下面是MSDN示例代码:
private void button2_Click(object sender, System.EventArgs e)
{
// Displays a SaveFileDialog so the user can save the Image
// assigned to Button2.
SaveFileDialog saveFileDialog1 = new SaveFileDialog();
saveFileDialog1.Filter = "JPeg Image|*.jpg|Bitmap Image|*.bmp|Gif Image|*.gif";
saveFileDialog1.Title = "Save an Image File";
saveFileDialog1.ShowDialog();
// If the file name is not an empty string open it for saving.
if(saveFileDialog1.FileName != "")
{
// Saves the Image via a FileStream created by the OpenFile method.
System.IO.FileStream fs =
(System.IO.FileStream)saveFileDialog1.OpenFile();
// Saves the Image in the appropriate ImageFormat based upon the
// File type selected in the dialog box.
// NOTE that the FilterIndex property is one-based.
switch(saveFileDialog1.FilterIndex)
{
case 1 :
this.button2.Image.Save(fs,
System.Drawing.Imaging.ImageFormat.Jpeg);
break;
case 2 :
this.button2.Image.Save(fs,
System.Drawing.Imaging.ImageFormat.Bmp);
break;
case 3 :
this.button2.Image.Save(fs,
System.Drawing.Imaging.ImageFormat.Gif);
break;
}
fs.Close();
}
}
并且,正如它所说,您需要注册事件处理程序:
this.button2.Click += new System.EventHandler(this.button2_Click);
UPDATE 2 (Web):
好吧,我看你实际上是在寻找一个网络解决方案。我考虑的是Windows而不是Web。以下是您在Web端必须做的事情。这是VB。. NET示例,但我假设您可以翻译:
string FileName = "Hello.doc";
string Filename = strFileName.Substring(0, FileName.LastIndexOf("."));
Response.AppendHeader("Content-Disposition", "attachment; filename=" + FileName);
Response.TransmitFile(Server.MapPath("~/Folder_Name/" + FileName));
Response.End();
我已经对这种方法进行了多次修改。您正在将XML文件发送回用户的浏览器。一旦它到达那里,用户必须决定如何处理它(通常是"打开这个文件,还是保存它?")。这是由浏览器控制的。
你可以通过包含一个内容类型头来帮助浏览器,告诉浏览器它正在查看的文件类型,以及它应该尝试打开它。这个头文件会让它调用Excel:
Response.AppendHeader("Content-Type", "application/vnd.ms-excel");
你经常会看到application/pdf,它会打开adobereader或其他用户正在使用的pdf阅读器。在这里,你需要使用内容类型"text/xml"。内容类型在这里不太重要,因为我们希望用户保存文件,而不是用应用程序打开它。
内容配置"附件"与"内联"有一点问题。两种方法都试一试,看看哪一种更适合你。其中一个(我不记得是哪个了)基本上忽略了您发送的建议文件名,而是使用ASP页面的名称。很烦人。Firefox至少将其记录为一个bug,而IE显然只是将其视为另一个"特性"。
使用Jquery (AJAX)有它的局限性,当它涉及到用户交互(具体参考保存对话框-即发送一个请求到一个asp页面在我的例子中,并期望一个文件[或内存流在我的情况下]返回,并想问用户他想保存它在哪里-因此不在服务器上)。
我找到了一个解决这个问题的方法,因为使用AJAX进行web相关调用是我的强项。正如这篇文章中提到的,还有一些改进的空间,但对我来说工作得很好,因此允许使用响应返回我的XML数据。write (x),这个"hack"允许用户将XML文件保存在他想要的任何地方:
Javascript来源:jQuery.download = function (url, data, method) {
//url and data options required
if (url && data) {
//data can be string of parameters or array/object
data = typeof data == 'string' ? data : jQuery.param(data);
//split params into form inputs
var inputs = '';
jQuery.each(data.split('&'), function () {
var pair = this.split('=');
inputs += '<input type="hidden" name="' + pair[0] + '" value="' + pair[1] + '" />';
});
//send request
jQuery('<form action="' + url + '" method="' + (method || 'post') + '">' + inputs + '</form>')
.appendTo('body').submit().remove();
};
};
ASP返回:
Response.Clear();
Response.ContentType = "text/xml";
Response.AddHeader("Content-disposition", "attachment; filename=test.xml");
Response.Write(yourXMLstring);
使用示例(javascript调用):
$.download("your_url_here", html_url_based_parameters_if_needed_here);
在这里得到这个有用的帖子:http://www.filamentgroup.com/lab/jquery_plugin_for_requesting_ajax_like_file_downloads/
希望这对将来的人有所帮助!