diff --git a/crates/dbx-core/src/transfer.rs b/crates/dbx-core/src/transfer.rs index 3d13eb7b0..a5c4cd328 100644 --- a/crates/dbx-core/src/transfer.rs +++ b/crates/dbx-core/src/transfer.rs @@ -1150,7 +1150,7 @@ pub fn escape_value_typed(val: &serde_json::Value, db_type: &DatabaseType, colum if *db_type == DatabaseType::Postgres { return quote_postgres_string_literal(&literal); } - let escaped = if is_postgres_family_target(db_type) { + let escaped = if is_postgres_family_target(db_type) || *db_type == DatabaseType::SqlServer { literal.replace('\'', "''") } else { literal.replace('\\', "\\\\").replace('\'', "''") @@ -6246,6 +6246,27 @@ mod tests { assert_eq!(sql, "INSERT INTO [dbo].[customers] ([name], [note]) VALUES\n(N'Tiếng Việt', N'O''Brien')"); } + #[test] + fn sqlserver_insert_preserves_backslashes_control_characters_quotes_and_unicode() { + let sql = generate_insert_typed( + &[String::from("escape_sequence"), String::from("line_break"), String::from("quote_and_unicode")], + &[ + Some(String::from("nvarchar(max)")), + Some(String::from("nvarchar(max)")), + Some(String::from("nvarchar(max)")), + ], + &[vec![json!(r#"\n"#), json!("line1\r\nline2"), json!("O'Brien / Tiếng Việt")]], + "notes", + "dbo", + &DatabaseType::SqlServer, + ); + + assert_eq!( + sql, + "INSERT INTO [dbo].[notes] ([escape_sequence], [line_break], [quote_and_unicode]) VALUES\n(N'\\n', N'line1\r\nline2', N'O''Brien / Tiếng Việt')" + ); + } + #[test] fn sqlserver_insert_formats_datetime_literals_with_supported_precision() { let sql = generate_insert_typed(