亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

當日期格式變量為“M/d/yy”且月份或日期為兩位數時,TO_DATE() 函數會出錯

當日期格式變量為“M/d/yy”且月份或日期為兩位數時,TO_DATE() 函數會出錯

C#
蝴蝶不菲 2021-11-28 19:56:52
我的日期格式因用戶的日期格式而異。當日期格式為 'M/d/yy' 時,它會給出錯誤,ORA-01821:日期格式無法識別。sDateFormat = CultureInfo.DateTimeFormat.ShortDatePattern;SELECT * FROM xxx WHERE yyy <= TO_DATE('" + sScheduleDate + "','"+sDateFormat+"')";//sScheduleDate ex: "11/15/18" //sDateFormat "M/d/yy"
查看完整描述

2 回答

?
瀟湘沐

TA貢獻1816條經驗 獲得超6個贊

我看到兩個問題:

  1. 就像 HoTTab1CH 說的:OracleParameters如果構建查詢,您應該始終使用(https://en.wikipedia.org/wiki/SQL_injection

  2. 您正在為 Oracle 使用 C#-Pattern。這可能會起作用(不變文化)機器人通常不會(分鐘)。

// This will get you the Pattern "MM/dd/yyyy"

string invariantPattern = CultureInfo.InvariantCulture.DateTimeFormat.ShortDatePattern;


// This will get me in a German-Environment the Pattern "dd.MM.yyyy"

string invariantPattern = CultureInfo.InvariantCulture.DateTimeFormat.ShortDatePattern;

這兩種模式都與 Oracle 無關。它們可能有效,但你不知道。您不得在 .Net 環境之外使用它們!


允許的是這樣的:


OracleCommand cmd = null; // You should have this one already initialized..


// Your Idea:

DateTime date = new DateTime(2018, 12, 31, 23, 59, 59);

string csharpPattern = "dd.MM.yyyy HH:mm:ss";

string oraclePattern = "dd.mm.yyyy HH24:MI:SS";

string toDateQuery = "to_date('" + date.ToString(csharpPattern) + "','" + oraclePattern + "')";

string sqlQuery = "SELECT * FROM mytable t WHERE t.mydate = " + toDateQuery;

cmd.CommandText = sqlQuery;

var reader = cmd.ExecuteReader();

// Do something...


// But... Better, shorter and correcter(?)

DateTime date2 = new DateTime(2018, 12, 31, 23, 59, 59);

cmd.CommandText = "SELECT * FROM mytable t WHERE t.mydate = :MYDATE";

cmd.Parameters.Add(new OracleParameter(":MYDATE", date2));

補充說明

桌子

CREATE TABLE TEST

(

  TESTDATE               DATE,

  TESTTIMESTAMP          TIMESTAMP(6),

  TESTTIMESTAMPTIMEZONE  TIMESTAMP(6) WITH TIME ZONE

)

C#-應用程序

DateTime d = DateTime.Now;


// Let OPD.Net do the work..

OracleCommand  cmd = con.CreateCommand();

cmd.CommandText = "INSERT INTO TEST VALUES(:TESTDATE, :TESTTIMESTAMP, :TESTTIMESTAMPTIMEZONE)";

cmd.Parameters.Add(new OracleParameter("TESTDATE", d));

cmd.Parameters.Add(new OracleParameter("TESTTIMESTAMP", d));

cmd.Parameters.Add(new OracleParameter("TESTTIMESTAMPTIMEZONE", d));

cmd.ExecuteNonQuery();


// Try to manually hit the OracleTypes - and loose the milliseconds..

cmd = con.CreateCommand();

cmd.CommandText = "INSERT INTO TEST VALUES(:TESTDATE, :TESTTIMESTAMP, :TESTTIMESTAMPTIMEZONE)";

cmd.Parameters.Add(new OracleParameter("TESTDATE", OracleDbType.Date, d, System.Data.ParameterDirection.Input));

cmd.Parameters.Add(new OracleParameter("TESTTIMESTAMP", OracleDbType.Date, d, System.Data.ParameterDirection.Input));

cmd.Parameters.Add(new OracleParameter("TESTTIMESTAMPTIMEZONE", OracleDbType.Date, d, System.Data.ParameterDirection.Input));

cmd.ExecuteNonQuery();


// Set everything correct (and redundant..)

cmd = con.CreateCommand();

cmd.CommandText = "INSERT INTO TEST VALUES(:TESTDATE, :TESTTIMESTAMP, :TESTTIMESTAMPTIMEZONE)";

cmd.Parameters.Add(new OracleParameter("TESTDATE", OracleDbType.Date, d, System.Data.ParameterDirection.Input));

cmd.Parameters.Add(new OracleParameter("TESTTIMESTAMP", OracleDbType.TimeStamp, d, System.Data.ParameterDirection.Input));

cmd.Parameters.Add(new OracleParameter("TESTTIMESTAMPTIMEZONE", OracleDbType.TimeStampTZ, d, System.Data.ParameterDirection.Input));

cmd.ExecuteNonQuery();

數據庫數據

| TESTDATE            | TESTTIMESTAMP              | TESTTIMESTAMPTIMEZONE             |

| 16/08/2018 11:07:23 | 16/08/2018 11:07:23,079714 | 16/08/2018 11:07:23,079714 +02:00 |

| 16/08/2018 11:07:23 | 16/08/2018 11:07:23,000000 | 16/08/2018 11:07:23,000000 +02:00 | 

| 16/08/2018 11:07:23 | 16/08/2018 11:07:23,079714 | 16/08/2018 11:07:23,079714 +02:00 |

如你看到的。示例程序確實選擇了錯誤的類型。在 cmd 中沒有顯式類型,ODP.Net 的工作是正確的。


OPD.Net 有每個 C#-Type 到 OracleDbTypes 的映射。您不必告訴 Oracle DateTime 是什么!


https://docs.oracle.com/cd/B28359_01/win.111/b28375/featTypes.htm


如果您開始在 C# 代碼中設置類型,則會得到雙重聲明。您的數據庫告訴您的客戶如何轉換變量。


如果您將 Db-Column 從 Date 更改為 Timestamp,您也必須更改您的 C#-App!如果您有多個應用程序訪問您的數據庫,您將有很多工作要做。


在某些情況下,例如使用具有可為空類型的數組,您應該設置類型,但通常不必這樣做。


查看完整回答
反對 回復 2021-11-28
?
四季花海

TA貢獻1811條經驗 獲得超5個贊

它無法識別,因為沒有這樣的“M”參數,這里是 TO_DATE() 的完整文檔https://www.techonthenet.com/oracle/functions/to_date.php


試試這個,正確的格式掩碼應該是 to_date('11/15/18', 'MM/DD/YY')


編輯:


為避免此問題,您最好在查詢中使用參數。這是一個小例子:


 DateTime date = //get your date here


 string myQuery= "SELECT * FROM xxx WHERE yyy <= :pDate";


 OracleCommand oraCmd = new OracleCommand();

 oraCmd.CommandType = CommandType.Text;

 oraCmd.Connection = OracleConnectionSource; // your connection


 OracleParameter oraParam = new OracleParameter();

 oraParam = oraCmd.Parameters.Add("pDate", OracleDbType.Date, date, ParameterDirection.Input);


 oraCmd.CommandText = myQuery;

 OracleDataReader oraDataReader = oraCmd.ExecuteReader();


查看完整回答
反對 回復 2021-11-28
  • 2 回答
  • 0 關注
  • 513 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號