Ssis-661 Review
| Platform | Steps |
|----------|-------|
| SQL Server 2016‑2019 | 1. Download the Cumulative Update from the Microsoft Update Catalog.
2. Run the installer on the SSIS server (the same machine that hosts the SSISDB).
3. Restart the SQL Server Integration Services service. |
| Azure‑SSIS Integration Runtime | 1. Create a new Integration Runtime based on SQL Server 2022 (which already contains the fix).
2. Re‑publish your packages to the new IR. |
| SSDT / Visual Studio | 1. Ensure you have Visual Studio 2022 with the latest Data Tools (v17.x).
2. The fix is baked into the Microsoft.SqlServer.IntegrationServices.Design assembly shipped with the update. |
Tip: After applying the patch, run the “Integration Services Catalog – Validate” command (
catalog.validate_package) on the affected packages. The validation will now surface any remaining conversion warnings.
| Role | What It Allows | When to Use |
|------|----------------|------------|
| ssis_admin | Full control over SSISDB (create, delete, deploy, start, stop, view logs) | Development or “owner” accounts. |
| ssis_operator | Execute packages, view logs, but cannot create/alter projects/folders | Production run‑time accounts. |
| ssis_logreader | Read execution logs only | Auditing/monitoring accounts. |
Example: Grant ssis_operator
USE SSISDB;
CREATE USER [DOMAIN\ETLUser] FOR LOGIN [DOMAIN\ETLUser];
EXEC sp_addrolemember N'ssis_operator', N'DOMAIN\ETLUser';
Important: After adding the user, you must refresh the catalog in SSMS (right‑click SSISDB → Refresh) to see the new role.
| Technique | How to implement |
|-----------|-----------------|
| Schema validation at the start of the package | Add an Execute SQL Task that runs SELECT TOP 0 * FROM dbo.Table and checks sys.columns via a script task; raise an error if a mismatch is detected. |
| Version‑controlled source objects | Keep a DDL script in source control and enforce a build‑time check that the production object matches the script. |
| Explicit column list in all sources | Never use SELECT *. |
| Package‑level data‑type constraints | Use the Data Flow → Advanced → Data Type property to lock a column to a specific type. |
| Deploy with “ValidateExternalMetadata = False” (cautiously) | In scenarios where you know the schema will change but you want the package to continue, set the property on the component, but be aware you lose early detection. |
| Continuous Integration (CI) testing | Add a step in your CI pipeline that runs the package against a test copy of the production database and fails the build on any SSIS‑661 (or other) error. |
Add a Validation Step
Enable SSIS Logging & Event Handlers
Automated Unit Tests
Monitor the SSIS Catalog
DT_WSTR → DT_STR. The error moves to the conversion component but the underlying bug remains.SSIS‑661 is a known bug that causes the Data Flow Task to crash (or silently drop rows) when a source column containing Unicode characters is mapped to a destination column that is defined as non‑Unicode (e.g., DT_STR). The issue typically surfaces in SQL Server Integration Services 2016–2022 when the source is Oracle, MySQL, or a flat‑file encoded in UTF‑8/UTF‑16.
Below is a concise guide that covers:
| Attribute | Value |
|-----------|-------|
| Bug ID | SSIS‑661 (internal Microsoft tracking number) |
| Affected components | OLE DB Source, Flat File Source, ADO.NET Source, Data Conversion, Derived Column |
| Symptom | Package fails with error “The conversion from data type Unicode string to non‑Unicode string resulted in a loss of data.” or the task hangs when the pipeline processes rows that contain characters outside the ASCII range (e.g., “é”, “ß”, “汉”). |
| First observed | SQL Server 2016 SP2, but reproduced on 2017, 2019, and 2022 RTM builds |
| Severity | High – data loss can go unnoticed in large‑scale ETL jobs | SSIS-661
Bottom line: SSIS‑661 is a data‑type conversion bug that mishandles Unicode → non‑Unicode casts when the underlying provider (ODBC/OLE DB) returns UTF‑16 strings but the SSIS metadata expects ANSI (DT_STR). The engine incorrectly assumes that the length of the target column is sufficient, leading to buffer overruns or silent truncation.