将日语文本保存到SQL数据库

时间:2017-02-21 13:33:30

标签: asp.net sql-server

我有一个asp.net应用程序,人们可以使用该应用程序将英语,法语和日语数据插入MS SQL数据库。我对DB进行了必要的更改,比如将Fields作为NVARCHAR,并在实际参数之前放置'N'前缀(因为我使用的是存储过程)。

这两个修复程序都无法正常工作,我可能会对Prefix做错了,如果你可以帮我解决这个问题会很棒:)

我正在使用的参数如下:

   @RewardId INT = NULL,
  @SupplierId INT = NULL,
  @RewardCode NVARCHAR(50) = NULL,
  @RewardDesc NVARCHAR(MAX) = NULL,
  @RStartDate DATETIME = NULL,
  @REndDate DATETIME = NULL,
  @RStatus BIT = NULL,
  @RCostPrice FLOAT = NULL,
  @PDCost FLOAT = NULL,
  @RStocks INT = NULL,
  @RewardTypeId INT = NULL,
  @RCategoryId INT = NULL,
  @RProductDesc NVARCHAR(MAX) = NULL,
  @RTermsCond NVARCHAR(MAX) = NULL,
  @DMId INT = NULL,
  @RRetailPrice FLOAT = NULL,
  @TemplateId INT = NULL,
  @RFreight FLOAT = NULL,
  @RTotalCost FLOAT = NULL,
  @MinimumQuantity INT = NULL,
  @RewardImageURL nvarchar(500) = null,
  @UpdateDate nvarchar(50) = null,
  @Rpoints nvarchar(50) = null  ,
   @ExpiryDateSetup nvarchar(50),
    @ExpiryNumberOfMonths nvarchar(50),
    @minimumstockcount int = NULL,
    @RewardRelationId int = null,
    @ParentRewardCode nvarchar(50) =null,
    @EstimatedSaving nvarchar(50) = null,
     @IsAirMilesMonday bit = False,
 @IsExpirymonthly bit = False,
 @IsPromoCodeEnabled nvarchar(50) = null,
  @IsLocked nvarchar(50) = null,
 @IsCompetition nvarchar(50) = null,
 @Sorting nvarchar(50) = null,
 @Tier nvarchar(50) = null  

我保存数据的方式如下:

 UPDATE
    Rewards
SET
    SupplierId = @SupplierId,
    RewardCode = @RewardCode,
    RewardDesc = 'N'+@RewardDesc,
    RStartDate = @RStartDate,
    REndDate = @REndDate,
    RStatus = @RStatus,
    RCostPrice = @RCostPrice,
    RStocks = @RStocks,
    RewardTypeId = @RewardTypeId,
    RCategoryId = @RCategoryId,
    RProductDesc = 'N'+@RProductDesc,
    RTermsCond = 'N'+@RTermsCond,
    RRetailPrice = @RRetailPrice,
    PDCost = @PDCost,
    RFreight = @RFreight,
    TemplateId = @TemplateId,
    RTotalCost = @RTotalCost,
    DMId = @DMId,
    MinimumQuantity = @MinimumQuantity,
    RewardImageURL = @RewardImageURL,
    UpdateDate = @UpdateDate,
    Points = @Rpoints   ,
    ExpiryDateSetup = @ExpiryDateSetup,
          ExpiryNumberOfMonths = @ExpiryNumberOfMonths,
          MinimumStockCount = @minimumstockcount,
          RewardRelationId = @RewardRelationId ,
          ParentRewardCode = @ParentRewardCode ,
          EstimatedSaving = @EstimatedSaving,
          IsAirMilesMonday = @IsAirMilesMonday ,
          IsExpirymonthly = @IsExpirymonthly,
          IsPromoCodeEnabled = @IsPromoCodeEnabled,
          Islocked = @IsLocked ,
          IsCompetition = @IsCompetition ,
          Sorting = @Sorting,
          tier = @tier
WHERE
    RewardId = @RewardId;  

********编辑***********

用于调用SP的代码定义如下:

Public Function Save(ByVal us As String, ByRef obrewardsold As cls_Rewards, ByRef obrewardsnew As cls_Rewards) As Boolean

    Dim sSQL As String
    Dim rtn As Boolean

    Dim rs As SqlDataReader = Nothing

    Try

        Save = True

        sSQL = "exec Rewards_upd"
        sSQL = sSQL & "  @SupplierId=" & gFixQuotes(SupplierId)

        sSQL = sSQL & ",  @RewardId=" & gFixQuotes(RewardId)
        sSQL = sSQL & " , @RewardCode=" & gFixQuotes(RewardCode)
        sSQL = sSQL & ", @RewardDesc=" & gFixQuotes(RewardDesc)
        sSQL = sSQL & ", @RStartDate=" & gFixQuotes(RStartDate)
        sSQL = sSQL & ", @REndDate=" & gFixQuotes(REndDate)
        sSQL = sSQL & ", @RStatus=" & gFixQuotes(RStatus)
        sSQL = sSQL & ", @RCostPrice=" & gFixQuotes(RCostPrice)
        sSQL = sSQL & ", @RRetailPrice=" & gFixQuotes(RRetailPrice)
        sSQL = sSQL & " ,@RFreight=" & gFixQuotes(RFreight)
        rtn = GetData(rs, sSQL)

1 个答案:

答案 0 :(得分:3)

ASP.NET和SQL Server都不需要任何技巧来使用Unicode。两者都本身支持Unicode。在出现奇怪字符的所有情况下,转换为ASCII 强制。表字段是varchar,或参数类型,或查询包含ASCII字符串文字。

有时,源文件本身可能保存为ASCII,导致在编译文件之前发生意外转换。默认情况下,Visual Studio切换到UTF8时,此特定问题消失。我不记得那发生的时间,可能是十年前,甚至更早。如果使用默认情况下不使用UTF8的文本编辑器,可能仍会出现。

要存储日语只需执行与每个其他Unicode字符串相同的操作 - 只需确保使用Unicode类型。

首先,确保该表使用nvarchar字段:

CREATE TABLE Rewards
(
    RewardId int not null primary key,
    RewardDesc nvarchar(50),
    ...
)

并且所有存储过程参数实际上都是nvarchar。之后,您唯一需要做的就是使用SqlDbType.NVarChar参数创建参数化查询:

var cmd=new SqlCommand("Rewards_upd",connection);
cmd.CommandType = CommandType.StoredProcedure;   
... 
// Assuming that RewardId is an integer 
cmd.Parameters.Add("@RewardId ", SqlDbType.Int).Value = RewardId;
// otherwise, parse it first. This will detect invalid input before executing the query
// cmd.Parameters.Add("@RewardId ", SqlDbType.Int).Value = int.Parse(RewardId);
cmd.Parameters.Add("@RewardDesc ", SqlDbType.NVarChar,50).Value = RewardDesc;

var reader=cmd.ExecuteReader();

存储过程本身并不需要做任何事情来支持Unicode输入,只需使用正确的类型:

CREATE PROCEDURE Rewards_upd (@RewardId int, @RewardDesc nvarchar(50)...)
AS
....
UPDATE Rewards
SET
    RewardDesc=@RewardDesc,
    ...
WHERE RewardId=@RewardId

N与日语字符串连接将添加一个无用的N字符。例如,以下查询将返回:

declare @text nvarchar(50)=N'如抜範浪偃壅國'

select @text, 'N' + @text

-------
如抜範浪偃壅國 N如抜範浪偃壅國

SQL Server会将N转换为Unicode,并将其添加到@text

另一方面,如果使用字符串文字,结果将会被破坏:

select '如抜範浪偃壅國'
-------
???????

如果您看到问号而不是日文文本,最可能的原因是您在某处使用ASCII字符串或文字。最有可能的是,您不使用参数化查询来调用存储过程并创建带有串联的SQL字符串

相关问题