Remkomplekty.ru

IT Новости из мира ПК
1 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Ошибка преобразования типа данных

Преобразование типов операндов в выражениях. Преобразования базовых типов данных, соответствующих целым числам, не всегда сохраняют значения переменных и могут приводить к трудно обнаруживаемым ошибкам

Преобразования базовых типов данных, соответствующих целым числам, не всегда сохраняют значения переменных и могут приводить к трудно обнаруживаемым ошибкам. В ряде случаев необходимо апеллировать к внутренним формам представления и действиям над ними. Преобразование формы представления может включать в себя:

— преобразование целой переменной в переменную с плавающей точкой, и наоборот;

— увеличение или уменьшение разрядности машинного слова, то есть «растягивание» или «усечение» целой переменной;

— преобразование знаковой формы представления целого в беззнаковую, и наоборот.

Уменьшение разрядности машинного слова всегда происходит путем отсечения старших разрядов числа, что может привести к ошибкам потери значащих цифр и разрядов:

char с; с = n; //Потеря значащих цифр (0x54)

Увеличение разрядности приводит к появлению дополнительных старших разрядов числа. При этом способ их заполнения зависит от формы представления целого и обеспечивает сохранение значения переменной в данной форме представления:

— для беззнаковых целых заполнение производится нулями;

— для целых со знаком дополнительные разряды заполняются одним и тем же значением знакового (старшего) разряда.

int n; unsigned u;

unsigned char uc=0x84; u = uc;

При преобразовании вещественного к целому происходит потеря дробной части, при этом возможно возникновение ошибок переполнения и потери значащих цифр, когда полученное целое имеет слишком большое значение.

double d1 =855.666, d2=0.5E16;

n = d1; // Отбрасывание дробной части

n = d2; // Потеря значимости

Преобразование знаковой формы в беззнаковую и обратно не сопровождается изменением значения целого числа и вообще не приводит к выполнению каких-либо действий в программе. В таких случаях транслятор «запоминает», что форма представления целого изменилась, и только.

d = n; // Значение d=0xFFFF (-1)

Самое главное для программиста, что в языке не предусмотрены средства автоматической реакции на ошибки преобразования типов данных, поэтому «отлавливать» их должна сама программа.

Преобразования типов данных операндов происходят в программе в трех случаях:

• при выполнении операции присваивания, когда значение переменной или выражения из правой части запоминается в переменной в левой части;

• при прямом указании на необходимость изменения типа данных переменной или выражения для чего используется операция явного преобразования типа;

• при выполнении бинарных операций над операндами различных типов, когда более «длинный» операнд превалирует над более «коротким», вещественное — над целым, а беззнаковое — над знаковым.

В последнем случае неявные преобразования выполняются в такой последовательности: короткие типы данных (знаковые и беззнаковые) удлиняются до int и double, а выполнение любой бинарной операции с одним long double, double, long, unsigned ведет к преобразованию другого операнда в тот же тип. Это может сопровождаться перечисленными выше действиями: увеличением разрядности операнда путем его «удлинения», преобразованием в форму с плавающей точкой и изменением беззнаковой формы представления на знаковую, и наоборот.

Следует обратить внимание на одну тонкость: если в процессе преобразования требуется увеличение разрядности переменной, то на способ ее «удлинения» влияет только наличие или отсутствие знака у самой переменной. Второй операнд, к типу которого осуществляется приведение, на этот процесс не влияет:

unsigned short d=0xFF00;

//=0x00000021 + 0x0000FF00 = 0x0000FF21

if (u > 5) . // «Истина»

Значения переменных без знака и со знаком равны FFFF или -1. Но результаты сравнения противоположны, так как во втором случае сравнение проводится для беззнаковых целых по их абсолютной величине, а в первом случае — путем проверки знака результата вычитания, то есть с учетом знаковой формы представления чисел.

Ошибка преобразования типов данных при импорте из Excel в SQL Server 2008

Каждый раз, когда я пытаюсь импортировать файл Excel в SQL Server, я получаю определенную ошибку. Когда я пытаюсь редактировать сопоставления, значение по умолчанию для всех числовых полей равно float. Ни одно из полей в моей таблице не имеет десятичных знаков в них, и они не являются типом данных денег. Они всего 8 цифр. Однако, поскольку я не хочу, чтобы мой первичный ключ хранился как float, когда он был int, как я могу это исправить? Это дает мне некоторую ошибку усечения, я при необходимости отправлю кеш экрана. Это обычная проблема?

Следует отметить, что я не могу импортировать файлы Excel 2007 (я думаю, что нашел это средство), но даже когда я пытаюсь импортировать файлы .xls, каждое значение, которое содержит цифры, автоматически импортируется как float и когда Я пытаюсь изменить его. Я получаю сообщение об ошибке.

6 ответов

9 Решение Pondlife [2012-03-21 19:26:00]

SSIS не неявно конвертирует типы данных, поэтому вам нужно сделать это явно. Менеджер соединений Excel может обрабатывать только несколько типов данных, и он пытается сделать лучшее предположение, основанное на первых нескольких строках файла. Это полностью документировано в документации SSIS.

У вас есть несколько вариантов:

  • Измените тип данных назначения на float
  • Загрузите таблицу «staging» с плавающей точкой данных с помощью мастера импорта, а затем INSERT в реальную таблицу назначения с помощью CAST или CONVERT для преобразования данных
  • Создайте пакет SSIS и используйте преобразование Преобразование данных для преобразования данных

Вы также можете отметить комментарии в Документах мастера импорта о сопоставлениях типов данных.

Отказ от того, что сказал Дерлоопкат, который все еще может потерпеть неудачу при конвертации (без обид Derloopkat), потому что Excel ужасен в этом:

  • Вставить из excel в блокнот и сохранить как обычно (.txt файл).
  • Внутри excel откройте указанный .txt файл.
  • Выберите следующий, поскольку он явно разделен на вкладку.
  • Выберите «none» для спецификатора текста, затем еще раз.
  • Выберите первую строку, удерживайте shift, выберите последнюю строку и выберите текстовую радиальную кнопку. Нажмите «Готово»
Читать еще:  Ошибка dxgi error device hung

Он откроется, проверьте его, чтобы он был точным, а затем сохраните его как файл excel.

Когда Excel находит смешанные типы данных в одном столбце, он догадывается, что является правильным форматом для столбца (большинство значений определяет тип столбца) и отклоняет все остальные значения, вставляя NULL. Но Excel делает это очень плохо (например, если столбец считается текстовым, и Excel находит номер, то решает, что число является ошибкой и вместо этого вставляет NULL, или если некоторые ячейки, содержащие числа, являются «текстовыми», они могут иметь значения NULL в целочисленный столбец базы данных).

  • Создайте новый новый лист excel с именем столбцов в первой строке
  • Отформатируйте столбцы как текст
  • Вставьте строки без формата (используйте формат CVS или скопируйте/вставьте в Блокнот, чтобы получить только текст)

Обратите внимание, что форматирование столбцов в существующем листе Excel недостаточно.

2 Shahbaz [2014-11-25 13:56:00]

Существует обходное решение.

  • Импортировать лист excel с числами как float (по умолчанию).
  • После импорта, Goto Table-Design
  • Измените DataType столбца с Float на Int или Bigint
  • Сохранить изменения
  • Изменить DataType столбца из Bigint на любой текстовый тип (Varchar, nvarchar, text, ntext и т.д.)
  • Сохранить изменения.

Кажется, что это действительно простое решение при решении проблем с типом данных.

В принципе, в конце строки подключения Excel добавьте ;IMEX=1;»

Это приведет к решению проблем типа данных, таких как столбцы, в которых значения смешаны с текстом и номерами.

Чтобы получить доступ к свойству подключения, щелкните правой кнопкой мыши на диспетчере соединений Excel ниже потока управления и нажмите свойства. Это будет направо в разделе explorer. Надеюсь, что это поможет.

Обходной путь, который следует рассмотреть в крайнем случае:

  • сохранить копию файла excel, изменить столбец для форматирования типа «текст»
  • скопируйте значения столбца и вставьте в текстовый редактор, сохраните файл (назовите его tmp.txt).
  • изменить данные в текстовом файле для начала и конца символом, чтобы механизм импорта SQL Server распознал текст. Если у вас есть модный редактор, используйте включенные инструменты. Я использую awk в cygwin на моем ноутбуке Windows. Например, я начинаю заканчивать значение столбца одной цитатой, например » $awk» ./tmp.txt > ./tmp2.txt «
  • скопируйте и вставьте данные из tmp2.txt поверх нужного столбца в файле excel и сохраните файл excel
  • запустите импорт sql-сервера для вашего измененного файла excel. убедитесь, что дважды проверьте тип данных, выбранный импортером, не является числовым. если это так, повторите вышеуказанные шаги с помощью другого набора символов

Данные в базе данных будут иметь кавычки после завершения импорта. вы можете позже обновить данные для удаления кавычек или использовать функцию «заменить» в запросе на чтение, например » замените ([dbo]. [MyTable]. [MyColumn], » », »)«

Ошибка преобразования типа данных varchar

В настоящее время у меня есть таблица со столбцом как varchar . Этот столбец может содержать цифры или текст. Во время некоторых запросов я рассматриваю его как столбец bigint (я делаю соединение между ним и столбцом в другой таблице, которая является bigint )

До тех пор, пока в этом поле были только цифры, не было никаких проблем, но в ту минуту, когда даже одна строка имела текст, а не цифры в этом поле, я получил «ошибку преобразования типа данных varchar в bigint .»ошибка, даже если в части WHERE я убедился, что ни одно из текстовых полей не появилось.

Чтобы решить эту проблему я создал представление следующим образом:

Но даже несмотря на то, что представление показывает только строки с числовыми значениями и приводит Mycol к bigint, я все равно получаю ошибку преобразования типа данных varchar в bigint при выполнении следующего запроса:

При выполнении запросов к виду он не должен знать, что происходит за ним! он должен просто видеть два больших поля! ( смотрите прикрепленное изображение, даже mssql management studio показывает поля представления как большие.)

8 Ответов

ОК. Я наконец-то создал представление, которое работает:

Спасибо AdaTheDev и CodeByMoonlight . Я использовал ваши два ответа, чтобы добраться до этого. (Спасибо и другим репликаторам, конечно)

Теперь, когда я делаю соединения с другими кольцами bigint или делаю что-то вроде ‘SELECT * FROM MyView where mycol=1’, он возвращает правильный результат без ошибок. Я предполагаю, что CAST в самом запросе заставляет оптимизатор запросов не смотреть на исходную таблицу, как сказал Кристиан Хейтер, возможно, происходит с другими представлениями

В идеале, вы хотите попытаться избежать хранения данных в этой форме — было бы целесообразно разделить данные BIGINT в отдельный столбец для повышения производительности и удобства запроса.

Однако вы можете сделать JOIN, как в этом примере. Обратите внимание, что я не использую ISNUMERIC() , чтобы определить, является ли он допустимым BIGINT, потому что это проверит неправильные значения, которые вызовут ошибку преобразования (например, десятичные числа).

Update: единственный способ, который я могу найти, чтобы заставить его работать для того, чтобы иметь предложение WHERE для конкретного целочисленного значения, не делая другого CAST() на предположительно bigint столбец в предложении where тоже, это использовать определяемую пользователем функцию:

Я действительно не думаю, что это отличная идея с точки зрения производительности, но это решение

Чтобы ответить на ваш вопрос о сообщении об ошибке: когда вы ссылаетесь на имя представления в другом запросе (предполагая, что это традиционное представление, а не материализованное представление), SQL Server эффективно выполняет макрос-замену определения представления в потребляющий запрос, а затем выполняет его.

Преимущество этого состоит в том, что оптимизатор запросов может выполнять гораздо лучшую работу, если он видит весь запрос, а не оптимизирует представление отдельно как «black box».

Следствием этого является то, что при возникновении ошибки описания ошибок могут выглядеть запутанными, поскольку механизм выполнения обращается к базовым таблицам для данных, а не к представлению.

Я не уверен, как обрабатываются материализованные представления, но я бы предположил, что они обрабатываются как таблицы, поскольку данные представления кэшируются в базе данных.

Сказав это, я согласен с предыдущими ответами — вы должны переосмыслить дизайн своей таблицы и разделить текстовые и целочисленные значения данных на отдельные столбцы.

Преобразование типов данных

Дата изменения: 20.07.2017

В программировании зачастую возникает нужда провести вычисления над переменными одного типа, а в результате получить другой. Например, при делении целых чисел получить вещественное. Когда значение одного типа заносится в переменную другого типа, выполняется преобразование типов данных. В C# это реализуется несколькими механизмами.

Неявное преобразование типов данных

Неявное преобразование происходит тогда, когда значение заносится в переменную иного типа без указаний этого в коде.

Для того, чтобы компилятор C# автоматически преобразовал тип данных, должны выполняться два условия:

  • Тип значения и тип переменной должны быть совместимы между собой;
  • Диапазон возможных значений типа переменной должен быть не меньше чем у типа значения.

В данном примере выполняется неявное преобразование, и переменная c в итоге будет иметь тип int. Это возможно благодаря тому, что byte и int являются целочисленными, а тип int полностью включает диапазон byte.

Еще один пример:

Несмотря на то, что число 815 входит в диапазон типа ushort, в этом случае появится сообщение об ошибке. Связано это с тем, что компилятор для неявного преобразования проверяет только вышеуказанные условия и смотрит только на типы, не обращая внимания на конкретные значения.

Явное преобразование типов данных

Если условия неявного преобразования не выполняются, но преобразование типов выполнить необходимо, используется приведение типов. Это указание целевого типа, в который должен быть преобразован результат вычислений, записываемое в скобках перед выражением.

Таким образом, переменная e получит тип double и значение 3,25. Если бы мы не использовали преобразование, то у этой переменной был бы тип int и значение 3 согласно правилам деления целых чисел в C#.

В случае с rnd, выполняется следующее правило: при преобразовании чисел с плавающей запятой в целые числа, их дробная часть отбрасывается.

А в случае с what все немного сложнее. При явном преобразовании компилятор не обращает внимания на диапазоны типов. А при исполнении программы, если происходит попытка занести в переменную значение, не находящееся в ее диапазоне (с более высокой разрядностью), то все старшие разряды стираются. Число 257 в двоичном представлении типа ushort выглядит как 00000001 00000001. При преобразовании в byte остается только последний байт 00000000, то есть 1.

Преобразование, при котором диапазон типа переменной не полностью покрывает диапазон типа значения, называется сужающим. Дабы избегать потери данных, как в предыдущем примере, нужно использовать проверку на переполнение.

Переполнение при сужающем преобразовании данных

Очевидно, что нельзя оставлять без внимания места в коде, в которых может иметь место потеря данных из-за переполнения. Иначе переменные могут принять неожиданное значение, что отразится на работе программы, а причину ошибки будет довольно трудно отследить.

По умолчанию, возникновение переполнения игнорируется. Для того чтобы в таком случае возникало соответствующее исключение, используется ключевое слово checked. Его можно поместить как перед определенным выражением, так и обозначить ним блок кода. Далее при возникновении исключения его можно обработать конструкцией try & catch.

bigger является случайным числом от 0 до 99999. В случае если это значение превысит диапазон типа short, то будет обработано исключение System.OverflowException и переменной smaller будет присвоено значение -1. Если же переполнение не произойдет, исключения не будет, и переменная smaller просто примет значение переменной bigger, но уже в типе short.

Оператор is

Для проверки возможности приведения объекта к некоторому типу в C# используется оператор is. Он проверяет, является ли объект экземпляром самого указанного типа или производного от него. Результатом бинарной операции с оператором is является логическое значение (true или false).

Пример использования оператора is:

Оператор as

Для преобразования совместимых ссылочных типов используется оператор as. Следует отметить, что при невозможности преобразования исключение не вызывается, а возвращается значение null. Это нужно учитывать при обработке результата преобразования с помощью as.

Вывод примера будет следующим:

1: it’s a SampleClass

2: it’s a string ‘welcome’

3: it’s not string or SampleClass

4: it’s not string or SampleClass

Преобразование типов с помощью класса Convert

Системный класс System.Convert содержит в себе методы, с помощью которых можно преобразовывать значения базовых типов данных, а также системного типа DateTime.

Convert содержит набор методов вида ToType, где вместо Type стоит системное название целевого типа значения (например ToChar, ToInt32, ToBoolean). Эти методы позволяют выполнять все возможные преобразования базовых типов C#.

Ошибка преобразования типа данных

Получаю следующую ошибку преобразования типа данных при запросе.
Вариант №1.
ADOCommand.CommandText := «INSERT INTO Table1 (Pole1) Values (100.45);
ADOCommand.Execute;
Pole1 — типа float.
Все замечательно работает.

Вариант №2.
Edit1.Text := «100.45»;
ADOCommand.CommandText := «INSERT INTO Table1 (Pole1) Values (» + Edit1.Text + «)»;
ADOCommand.Execute;
Не работает.
Ошибка: «100.45» is not a valid floating point value.

Может проблема в длительных Новогодних праздниках?


dioman © ( 2006-01-09 11:53 ) [1]


> Может проблема в длительных Новогодних праздниках?


Fay © ( 2006-01-09 12:05 ) [2]

2 VadimSpb (09.01.06 11:36)
не верю


VadimSpb ( 2006-01-09 12:11 ) [3]

Я очень хочу этому не верить.
Но, бытие определяет сознание.


Fay © ( 2006-01-09 12:27 ) [4]

2 VadimSpb (09.01.06 12:11) [3]
Это космические лучи. Сто пудов 8)


Anatoly Podgoretsky © ( 2006-01-09 12:33 ) [5]

VadimSpb (09.01.06 11:36)
Ты где то нас обманываешь


tech © ( 2006-01-09 14:37 ) [6]

ADOCommand.CommandText := «INSERT INTO Table1 (Pole1) Values (» + Trim(Edit1.Text) + «)»;


Fay © ( 2006-01-09 14:52 ) [7]

2 tech © (09.01.06 14:37) [6]
Попробуйте
ADOCommand.CommandText := «INSERT INTO Table1 (Pole1) Values ( 100.45 )»;


Desdechado © ( 2006-01-09 14:56 ) [8]

используй параметры и все будет ок
проблема в непонимании разделителя целой и дробной части
на клиенте и сервере они могут быть разные, причем как понастройкам ОС, так и сервера БД


Fay © ( 2006-01-09 15:00 ) [9]

2 Desdechado © (09.01.06 14:56) [8]
На сервере всегда точка. В «100.45» тоже точка. Видимо, не очень разные.


Anatoly Podgoretsky © ( 2006-01-09 15:51 ) [10]

Desdechado © (09.01.06 14:56) [8]
Ну он вроде как пишет, что точка, но думаю обманывает.


Dioman © ( 2006-01-09 15:52 ) [11]

в обоих примерах на сервер идут одинаковые строки.


sniknik © ( 2006-01-09 16:00 ) [12]

> в обоих примерах на сервер идут одинаковые строки.
если выполняется тот код, что показан нам. (. )

но думаю он опустил разные «несущественные» (с его точки зрения) детали, и мы здесь видим совершенно не то, что у него выполняется (и дает ошибку), т.е. он нас попросту обманывает. или «разводит» (что тоже возможно).


VadimSpb ( 2006-01-09 16:23 ) [13]

Да-а, уж и не думал, что в обмане обвинят . :-((
Мне совсем не до смеха, дурка полная. В отладчике вижу две одинаковые стринги. Пример простой, поробуйте сами.
А запятую там в принципе нельзя ставить — это и ежу ясно.


dioman © ( 2006-01-09 16:25 ) [14]


VadimSpb ( 2006-01-09 16:27 ) [15]

Очень полезный совет. Часто помогает?


Fay © ( 2006-01-09 16:40 ) [16]

2 VadimSpb (09.01.06 16:23) [13]
> Пример простой, поробуйте сами
Всё ОК


parovoZZ © ( 2006-01-09 16:41 ) [17]

Я тут мимо пробегал.
Может ОН думает, что это не текст, а цифры. Или наоборот. Гы. А может ему фиолетово?


Dioman © ( 2006-01-09 16:46 ) [18]


> VadimSpb (09.01.06 16:27) [15]
>
> Очень полезный совет. Часто помогает?
>

не часто, но может помочь 😉


VadimSpb ( 2006-01-09 16:53 ) [19]


> Я тут мимо пробегал.
> Может ОН думает, что это не текст, а цифры. Или наоборот.
> Гы. А может ему фиолетово?

Будете проходить мимо — проходите мимо.


VadimSpb ( 2006-01-09 19:49 ) [20]

Однако, сделал. Всем спасибо.
«Забытых» процессов не было, проверил сразу.
Все проще и одновременно грустнее.
Просто заменил Edit на новый — и все!
Похоже, что это результат перехода с D7 на D2005. Уже не в первый раз сталкиваюсь с тупыми проблемами (напр. поведение MessageBox, пришлось переписать на API и пр., а оказалось лечится SP1,2,3).
В Accesse как-то проходило, а сейчас правлю под SQL SERVER вот и полезло.


Desdechado © ( 2006-01-09 20:03 ) [21]

повторю для тех, кто в танке
используй параметры, не будет надуманных и не очень проблем


VadimSpb ( 2006-01-09 20:14 ) [22]

Забавно было видеть именно ошибку преобразования типа данных.
Это откуда? Формируется и передается именно стринга.


sniknik © ( 2006-01-09 20:18 ) [23]

> В Accesse как-то проходило, а сейчас правлю под SQL SERVER вот и полезло.
ни Access ни MSSQL здесь ни причем,
ошибка:
> «xxxxxx» is not a valid floating point value.
дельфевая, это ошибка преобразования строки к флоату (EConvertError). преобразований в коде ([0]) нет. делаем вывод — эта часть «опущена как несущственная»
в MSSQL было бы (на преобразование)
Error converting data type xxxxxx to float
а в Access типа
Несоответствие типов данных в выражении условия отбора
делаем следующий вывод — ты до сих пор пытаешся «пудрить нам мозги» списывая собственные промахи на «неведомый подземный стук».


sniknik © ( 2006-01-09 20:22 ) [24]

советую всеже приводить код as is, и с запасом +- несколько строк, а не только то что сами считаете важным «избранное так сказать», очищая с вашей точки зрения «шелуху» убираете и то что пытаетесь донесть (если бы знали, что именно нужно, то сами бы легко разпознали ошибку, а раз не распознали. ).


VadimSpb ( 2006-01-09 20:24 ) [25]


> делаем следующий вывод — ты до сих пор пытаешся «пудрить
> нам мозги» списывая собственные промахи на «неведомый подземный
> стук».

Жаль что встретил определенное непонимание.
Каждый может делать свои выводы.

Ссылка на основную публикацию
ВсеИнструменты
Adblock
detector
×
×