Chapter 3: Make APPX Files Available to SQL
Check Every COUNTRY Record and Field
The independent native sample contains eight records and nine fields. The ODBC result also contains eight records, but the names are C, F, I, N, R, U, U, U. The native names are Canada, France, Ireland, Netherlands, Russia, UK, United States and USA.
All six numeric/date/RAW COUNTRY fields agree in all eight records. The Unicode name field agrees in zero records; the other Unicode fields agree only where the native value is empty. The separate ten-record, 24-field PROSPECT comparison produces the same distinction. Together these checks compare 312 field values. A subsequent fresh-process comparison after removing the inherited RDBMS debug-log overrides reproduced exactly the same field differences in both complete samples. This repeats the data result; it does not establish that every diagnostic setting or connection wait has been isolated.
Compare the native expected CSV with the observed ODBC CSV. Treat the damaged text as unusable. name = ? with Canada returns zero rows; no_words >= ? AND name <> ? with 2 and Canada incorrectly returns three rows including Canada. This affects filtering as well as display. There is no accepted client-only repair. The 5.5.4 32-bit sample-data recipe is a separate verified engine/gateway combination, not a downgrade or driver-replacement recommendation for an existing application.
Check actual non-ASCII values
COUNTRY's sample names use ASCII characters stored in Unicode fields. That checks the field storage path, but cannot establish support for other scripts. PROSPECT contains actual euro signs, accented Latin and Cyrillic. Its native values were decoded independently from the current APPX records before comparison with ODBC.
| Numeric key and field | Native APPX value | Observed ODBC value |
|---|---|---|
2, salesrep_name | Mona € Atwater | M |
20, salesrep_name | Chambéry Anderson | C |
21, address_1 | 43 Buffalo Place € | 4 |
40, division_name | Автозапчасти | U+0010 U+0004 |
40, salesrep_name | Джо Байден | U+0014 U+0004 |
The last two results are control characters, written here as code points so they remain visible. They are not the literal words U+0014 and U+0004. The failure is therefore broader than every value being shortened to one character.
Run the numeric-key checks before testing text predicates. These three individual queries completed without putting non-ASCII text into their predicates:
SELECT prospect_no, salesrep_name FROM DMO_DMO_PROSPECT WHERE prospect_no = 2; SELECT prospect_no, salesrep_name FROM DMO_DMO_PROSPECT WHERE prospect_no = 20; SELECT prospect_no, salesrep_name FROM DMO_DMO_PROSPECT WHERE prospect_no = 40;
Compare the native Unicode sample with the observed code-point representation. The combined numeric-key query also completed and selected all four sample records, with the same damaged text. Its earlier bounded attempts waited during connection Open, before SQL execution. A later completed query does not erase those connection waits or establish a reliable connection-time workaround.
Check expressions and selection separately
| Operation on the current native sample | Observed result |
|---|---|
CHAR_LENGTH(name) | 1 for all eight COUNTRY names, rather than their native lengths. |
UPPER(name) and SUBSTRING(name,1,3) | Expressions execute, but return damaged text. |
name = 'Canada', name LIKE 'Can%', and name IN ('Canada','France') | Zero rows, despite the corresponding native records being present. |
name = 'C' | Zero rows; this is the expected negative control. It does not show that filtering uses the displayed first character. |
SELECT DISTINCT name ... ORDER BY name | Eight rows, displayed as C, F, I, N, R, U, U, U. The row count alone passes neither uniqueness nor value acceptance. |
COUNT(DISTINCT name) | 6, although the native file contains eight distinct names. |
GROUP BY name with COUNT(*) | Six groups. UK, United States and USA collapse into a displayed U group with count 3. |
ORDER BY name DESC | Rows display U, U, U, R, N, I, F, C; the full native names remain lost. |
no_words >= 2 ORDER BY name | The three expected records are selected, but their projected names are C, N and U. |
CHAR_LENGTH(salesrep_name) | 1 for the first nine PROSPECT records and 2 for the Cyrillic record; neither result matches its native text length. |
RAW added_by and changed_by | All ten PROSPECT records agree with their native values. |
| COUNTRY name self-join | A later fresh connection executed after removing the inherited RDBMS trace overrides and returned zero rows, rather than the eight expected self-pairs. Earlier Open waits remain preserved. |
PROSPECT self-join on numeric prospect_no | All ten expected key pairs agree with the native records. This does not establish text-key join correctness. |
Numeric GROUP BY no_words | The three groups match native data: 0 has one record, 1 has four, and 2 has three. |
date_added IS NULL ORDER BY name | Four rows, displayed as F, N, U, U. The projected names differ from the native values; duplicated damaged names do not establish every row association. |
Literal and parameter predicates for the euro, accented and Cyrillic sales representative names also returned zero rows in the executions that completed. The euro literal predicate also completed in a later fresh process and returned zero rows. Earlier connection Open waits remain in the receipts; they are not SQL execution results.
Check the input path without reading a text field
Separate a stored-field failure from conversion of text supplied by the client. The input controls select a literal, or CAST(? AS VARCHAR(120)), from the record with numeric key 2. Parameter controls bind VarChar and NVarChar separately; their result expression is still VARCHAR.
ASCII Canada, Mona € Atwater and Chambéry Anderson survive all three completed input paths: literal, VarChar parameter and NVarChar parameter. The Cyrillic literal, VarChar and NVarChar controls all return question marks in completed executions; earlier NVarChar attempts waited during connection Open. Combining e plus U+0301 returns e? through the literal and both parameter paths. The supplementary character U+1F642 returns ?? through the literal and both parameter paths.
These controls document the tested conversions. They do not establish support for an NVARCHAR result type, native APPX storage of combining or supplementary characters, or a particular SQL collation. Loss through a VARCHAR expression does not, by itself, identify an APPX storage defect. Keep those limits distinct from the independently reproduced damage when reading existing native Unicode fields.
The SQL and parameter matrix covers 51 distinct cases across 72 bounded workers. Every case eventually executed: 38 comparisons differ from the independent expectation and 13 controls match. Twenty connection Open waits remain in the attempt history, including cases that later completed. These are comparison counts, not a count of separate defects. The two complete sample-file repeats after trace cleanup are additional checks.
Check ANSI and Unicode API calls
A separate native Windows ODBC check uses SQLConnectA/SQLExecDirectA and SQLConnectW/SQLExecDirectW, then retrieves the result independently as SQL_C_CHAR or SQL_C_WCHAR. Each case has a fresh process and connection. Returned buffer bytes are retained; the measured Windows ANSI code page is 1252.
| Value or control | ANSI API, narrow result | ANSI API, wide result | Unicode API, narrow result | Unicode API, wide result |
|---|---|---|---|---|
| Literal Canada | Canada | Canada | Canada | Canada |
| Native Mona € Atwater, numeric key 2 | M | M | M | M |
| Native Chambéry Anderson, numeric key 20 | C | C | C | C |
| Native Джо Байден, numeric key 40 | U+0014 U+0004 | U+0014 U+0004 | U+0014 U+0004 | U+0014 U+0004 |
| Cyrillic input literal | Question marks | Question marks | Question marks | Question marks |
| Supplementary input literal U+1F642 | ?? | ?? | No execution: Open wait | ?? |
Trailing SQL character padding is omitted from the displayed results. These checks reproduce native-field damage through all four API/buffer combinations; requesting a wide result buffer is not a verified repair. The attempts retain ten connection Open waits; the Unicode-API/narrow-buffer supplementary-input case still has no execution result after its bounded attempts. No value is inferred for that case.
The supplied driver does not export SQLConnectW. Windows can map a Unicode application's calls and buffers onto an ANSI driver, so a successful wide API call alone does not prove Unicode support end to end. See Microsoft's Unicode driver rules. Keep the measured stored-field failures separate from code-page conversion of input literals.
Check every saved export and client document after refresh. UTF-8 CSV, JSON or a spreadsheet can faithfully preserve already damaged ODBC text; changing the export encoding cannot reconstruct the native value. The Excel save and refresh check compares all 72 saved COUNTRY values rather than accepting its eight-row count alone.