如何将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);

如何将PL/SQL输出(clob)保存为XML文件

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/

希望这对将来的人有所帮助!