Tag Archives: .NET

SqlBulkCopy 載入資料的資料精準度錯誤

小心

https://forums.asp.net/t/1300113.aspx?SqlBulkCopy+Precision+Error+from+C+Double+to+Sql+Decimal+

.NET 只有浮點數(single/double),並不支援 SQL Server 的 Numeric/Decimal 或 Oracle 的 Number,當使用 SqlBulkCopy 載入資料到 SQL Server 的目的欄位型別為 Numeric/Decimal 有指定小數位數十,可能發生轉換時,精準度差最小位數。

以上述的連結範例而言 27.2 放到 Numeric(10,4) 會造成 27.1999,若放到 Numeric(10,5),則是 27.19999。

可以採用如提問者自己在下方的解法,先存到中介 table,對應欄位宣告成 float,對應 .NET 使用的 double,然後再從中介轉到真正的目標 table,這時 float 轉 numeric,則數值就會正確。

廣告

當過濾欄位是 char/varchar 時,透過 SqlCommand 搭配 SqlParameter 時,大量存取會有效能考量

最近幫朋友壓測時,發現的問題。

依據 SQL Server 的 Data Type Precedence https://msdn.microsoft.com/en-us/library/ms190309.aspx

  1. user-defined data types (highest)
  2. sql_varian t
  3. xml
  4. datetimeoffset
  5. datetime2
  6. datetime
  7. smalldatetime
  8. date
  9. time
  10. float
  11. real
  12. decimal
  13. money
  14. smallmoney
  15. bigint
  16. int
  17. smallint
  18. tinyint
  19. bit
  20. ntext
  21. text
  22. image
  23. timestamp
  24. uniqueidentifier
  25. nvarchar (including nvarchar(max) )
  26. nchar
  27. varchar (including varchar(max) )
  28. char
  29. varbinary (including varbinary(max) )
  30. binary (lowest)

代表輸入的條件參數若是 unicode,而目標欄位是 char/varchr/text,將會是欄位內所有的紀錄值先轉型成 unicode,再跟輸入條件比較。

範例程式碼:

use tempdb

drop table if exists t1

create table t1(c1 int identity primary key,c2 char(6),c3 char(10),c4 varchar(50),c5 datetime2(7) default(sysdatetime()),
c6 uniqueidentifier default(newsequentialid()),c7 bigint default(0))

set nocount on

declare @i int=0
while @i<100000
begin
insert t1(c2,c3,c4) values(right(‘000000’+convert(varchar(6),@i),6),
right(‘0000000000’+convert(varchar(6),@i),10),rand())
set @i+=1
end

select * from t1

create index idx on t1(c2,c3,c4)
go
create proc sp @c2 char(6),@c3 char(10),@c4 varchar(50)
as
select c1 from t1 where c2=@c2 and c3=@c3 and c4=@c4
go

簡單利用 console 程式測試

using System;
using System.Data.SqlClient;

namespace ConsoleApplication4
{
class Program
{
static void Main(string[] args)
{
using (SqlConnection cnn = new SqlConnection(“Data Source=.;Initial Catalog=tempdb;integrated security=sspi"))
{
SqlCommand cmd = new SqlCommand(“select c1 from t1 where c2=@c2 and c3=@c3 and c4=@c4″);
                cmd.Parameters.Add(new SqlParameter(“c2″, “000000″));
cmd.Parameters.Add(new SqlParameter(“c3″, “0000000000″));
cmd.Parameters.Add(new SqlParameter(“c4″, “0.0558658″));
                cmd.Connection = cnn;

SqlCommand cmd2 = new SqlCommand(“select c1 from t1 where c2=@c2 and c3=@c3 and c4=@c4″);
                cmd2.Parameters.Add(new SqlParameter(“c2″, System.Data.SqlDbType.Char,6));
cmd2.Parameters.Add(new SqlParameter(“c3″, System.Data.SqlDbType.Char, 10));
cmd2.Parameters.Add(new SqlParameter(“c4″, System.Data.SqlDbType.VarChar, 50));
                cmd2.Parameters[0].Value = “000000″;
cmd2.Parameters[1].Value = “0000000000″;
cmd2.Parameters[2].Value = “0.0558658″;
cmd2.Connection = cnn;

SqlCommand cmd3 = new SqlCommand(“sp");
cmd3.CommandType = System.Data.CommandType.StoredProcedure;
cmd3.Parameters.Add(new SqlParameter(“c2″, “000000″));
cmd3.Parameters.Add(new SqlParameter(“c3″, “0000000000″));
cmd3.Parameters.Add(new SqlParameter(“c4″, “0.0558658″));
cmd3.Connection = cnn;

cnn.Open();
long l = DateTime.Now.Ticks;
int times = 100000;
for(int i=0;i<times;i++)
{
//exec sp_executesql N’select c1 from t1 where c2=@c2 and c3=@c3 and c4=@c4′,N’@c2 nvarchar(6),@c3 nvarchar(10),@c4 nvarchar(9)’,@c2=N’000000′,@c3=N’0000000000′,@c4=N’0.0558658′
SqlDataReader dr = cmd.ExecuteReader();
dr.Close();
}
Console.WriteLine((DateTime.Now.Ticks – l).ToString());

System.Threading.Thread.Sleep(3000);

l = DateTime.Now.Ticks;
for (int i = 0; i <times; i++)
{
//exec sp_executesql N’select c1 from t1 where c2=@c2 and c3=@c3 and c4=@c4′,N’@c2 char(6),@c3 char(10),@c4 varchar(50)’,@c2=’000000′,@c3=’0000000000′,@c4=’0.0558658′
SqlDataReader dr = cmd2.ExecuteReader();
dr.Close();
}
Console.WriteLine((DateTime.Now.Ticks – l).ToString());
System.Threading.Thread.Sleep(3000);

l = DateTime.Now.Ticks;
for (int i = 0; i < times; i++)
{
//exec sp @c2=N’000000′,@c3=N’0000000000′,@c4=N’0.0558658′
SqlDataReader dr = cmd3.ExecuteReader();
dr.Close();
}
Console.WriteLine((DateTime.Now.Ticks – l).ToString());
}
}
}
}

 

若 .NET 未指定 type,會自動賦予 nvarchar,導致欄位為 char 的要轉成 nvarchar 再行比較,以此例而言,也就是每次比較就需要轉 10 萬筆,3 欄位的紀錄值:

image

就單次查詢時,SQL Server 的執行計畫判讀不覺得有效能差,所以彼此占比相同。

但重複執行 10 萬次後,時間上,可以看得出來,因為指定正確的欄位型態,或是 Stored Procedure 只需要輸入參數時轉對參數型態,實際語法比較時,不需逐筆轉換,所以效率較佳。

image

就總 CPU 耗用而言,因為無法平行運算,轉資料型態導致 CPU 要跑得比較久,但只會操死一顆 CPU

image

VS 2013 Update 4 造成 Web Template 損毀

狀況:

image

確定後的錯誤訊息

image

透過控制台修復

image

image

修復後就正常了

參考: http://stackoverflow.com/questions/26955822/visual-studio-2013-update-4-has-broken-web-templates

Web Service 透過 trace.axd 觀察執行狀況

HttpContext.Current.Trace.Write

http://forums.asp.net/t/1099533.aspx?Debug+Tracing+in+a+Web+Service

修改連接到 TFS 的身分

若不小心錯改工作機器連接到 TFS 的身分,例如 NuGet 更新的專案已經放在 TFS Source Control,但 Workspace 在本基存取有問題

image

在對話窗中輸入了其他帳號

image 

則在"控制台"內的"使用者帳戶"之"管理您的認證"會記住你的登入方式,而導致 VS Team Explorer 都以其他帳號登入 TFS,若要修改需透過控制台

image

參考:http://blogs.msdn.com/b/visualstudioalm/archive/2012/08/29/clearing-the-credentials-for-connecting-to-a-team-foundation-server.aspx

Release Management 和 SharePoint 裝在同一台會有問題

感謝 Cary Hsu 提供的解法:

http://www.colinsalmcorner.com/post/fix-release-management-service-unavailable-503

http://myalmblog.com/2014/03/01/error-installing-release-management-client/

若安裝的當下無法設定 RM(例如上述問題導致安裝成功但因 Services 起不來而無法設定),事後要修改,則可以到以下路徑執行相關的程式

  • RM Services 可利用"開始"目錄內 “Microsoft Visual Studio Team Foundation Server 2013″ 之下的 “Team Foundation Server 2013 Release Management 伺服器",實際檔案位置:C:\Program Files (x86)\Microsoft Visual Studio 12.0\Release Management\bin\ReleaseConfigurationUI.exe
  • RM Client 可利用"開始"目錄內 “Visual Studio 2013″ 之下的 “Visual Studio 2013 Release Management 用戶端",實際檔案位置:C:\Program Files (x86)\Microsoft Visual Studio 12.0\Release Management\Client\bin\ReleaseManagementConsole.exe
  • Agent 要利用 C:\Program Files (x86)\Microsoft Visual Studio 12.0\Release Management\bin\DeploymentAgentConfigUI.exe

在以下這個 MVA 有談到安裝,以及這個問題

http://www.microsoftvirtualacademy.com/Content/ViewContent.aspx?et=8379&m=8374&ct=28411

ADO.NET 的 Connection String 提供那些屬性

透過 Visual Studio 的伺服器總管視窗,檢視 ADO.NET 提供存取 SQL Server 相關的 Conneciton String 設定屬性名稱:

image

Unit Test Generator

為 VS 2012 自動建 Unit Test,但若待測的 Class 剛好取名成關鍵字,會有 COM 的 HResult 錯誤 🙂

http://visualstudiogallery.msdn.microsoft.com/45208924-e7b0-45df-8cff-165b505a38d7

Windows 系統提供遠端存取 WMI 所需完成的設定

參考小妙的 blog:http://chousmiao.wordpress.com/2012/10/09/wmi%e7%a8%8b%e5%bc%8f%e5%9f%b7%e8%a1%8c%e9%81%a0%e7%ab%af%e9%9b%bb%e8%85%a6%e8%a8%ad%e5%ae%9a%e5%95%8f%e9%a1%8c/

利用 JavaScriptSerializer 序列化/反序列化 JSON 字串

朋友的需求,簡單 sample code