c# database教學 - SQLException:字符串或二進制數據將被截斷




server教學 connection (10)

我有一個C#代碼,批量處理很多插入語句。 在執行這些語句時,我得到“字符串或二進制數據將被截斷”錯誤和事務roledback。

要找出導致這種情況的insert語句,我需要在SQLServer中逐個插入,直到我遇到錯誤。

是否有巧妙的方法來查找哪個語句和哪個字段使用異常處理導致此問題? (SQLEXCEPTION)


Answers

在我們自己的情況下,我增加了sql表允許的字符或字段大小,該大小小於從前端發布的總字符數。 因此,解決了這個問題。


這取決於您如何進行插入調用。 全部作為一個電話,還是作為交易中的個別電話? 如果單獨調用,則為yes(當您遍歷調用時,捕獲失敗的調用)。 如果一個大的電話,那麼沒有。 SQL正在處理整個語句,因此它不受代碼的影響。


使用Linq To SQL,我通過記錄上下文來調試,例如。 Context.Log = Console.Out然後掃描SQL以檢查是否有任何明顯的錯誤,有兩個:

-- @p46: Input Char (Size = -1; Prec = 0; Scale = 0) [some long text value1]
-- @p8: Input Char (Size = -1; Prec = 0; Scale = 0) [some long text value2]

我通過掃描表模式與值找到的最後一個,字段是nvarchar(20)但值為22個字符

-- @p41: Input NVarChar (Size = 4000; Prec = 0; Scale = 0) [1234567890123456789012]


通常,您要插入的值大於允許的最大值。 例如,數據列最多只能包含200個字符,但您要插入201個字符的字符串


  1. 獲取導致問題的查詢(如果沒有源代碼,也可以使用SQL事件探查器)
  2. 刪除所有WHERE子句和其他不重要的部分,直到基本上只剩下SELECT和FROM部分
  3. 添加WHERE 0 = 1(這將只選擇表結構)
  4. 在FROM子句之前添加INTO [MyTempTable]

你最終會得到類似的東西

SELECT
 Col1, Col2, ..., [ColN]
INTO [MyTempTable]
FROM
  [Tables etc.]
WHERE 0 = 1

這將在您的數據庫中創建一個名為MyTempTable的表,您可以將其與目標表結構進行比較,即您可以比較兩個表上的列以查看它們的不同之處。 這是一個解決方法,但它是我發現的最快的方法。


當您必須將字符或值多於您在Database表中指定的字符或值時,通常會發生這種類型的錯誤:您指定transaction_status varchar(10),但實際上您嘗試存儲包含19個字符的_transaction_status。 這就是你在這段代碼中遇到這種錯誤的原因


BEGIN TRY
    INSERT INTO YourTable (col1, col2) VALUES (@val1, @val2)
END TRY
BEGIN CATCH
    --print or insert into error log or return param or etc...
    PRINT '@val1='+ISNULL(CONVERT(varchar,@val1),'')
    PRINT '@val2='+ISNULL(CONVERT(varchar,@val2),'')
END CATCH

通常,沒有辦法確定哪個特定語句導致錯誤。 如果您正在運行多個,您可以觀看分析器並查看最後完成的語句,看看之後的語句可能是什麼,但我不知道這種方法是否適合您。

在任何情況下,您的一個參數變量(及其中的數據)對於它試圖存儲數據的字段而言太大。根據列大小檢查參數大小,並且相關字段應該很快就會明顯。


當SQL Server列的數據類型的長度小於輸入到條目表單中的數據的長度時,會發生此類錯誤。


我的答案可能會遲到,但我認為它可以幫助新手。 除非更改如下所述,否則您不會看到執行日誌。

2實施Log4net時必須更改文件。

  1. 在項目中添加log4net.dll的引用。
  2. 的app.config
  3. 您將在其中實現日誌的文件。

在[ app.config ]裡面:

首先,在'configSections'下,你需要添加下面的一段代碼;

<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />

然後,在'配置'區塊下,你需要寫下一段代碼(這段代碼是根據我的需要定制的,但它的作用就像魅力一樣)。

<log4net debug="true">
    <logger name="log">
      <level value="All"></level>
      <appender-ref ref="RollingLogFileAppender" />
    </logger>

    <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
      <file value="log.txt" />
      <appendToFile value="true" />
      <rollingStyle value="Composite" />
      <maxSizeRollBackups value="1" />
      <maximumFileSize value="1MB" />
      <staticLogFileName value="true" />

      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date %C.%M [%line] %-5level - %message %newline %exception %newline" />
      </layout>
    </appender>
</log4net>

內部呼叫類

在你要使用這個log4net的類中,你需要聲明下面的一段代碼。

 ILog log = LogManager.GetLogger("log");

現在,您可以在同一個班級中隨時隨地撥打電話記錄。 以下是您在操作時可以調用的方法之一。

log.Error("message");




c# sql sql-server