2015-03-19 4 views
3

Я пытаюсь вставить значение с плавающей точкой из одной таблицы в другую, но я получаю сообщение об ошибке в теме этого поста:хранимых процедур - Ошибка преобразования типа данных VARCHAR плавать

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

Оба поля в обеих таблицах имеют значение float. Значения представляют собой широты и долготы для почтовых индексов. Пример широты/долготы будет:

45,895698 -72,365896

Вот несколько фрагментов моего кода:

declare @v_latitude float 
declare @v_longitude float 

-- Grab Latitude & Longitude -- 
if @v_zip_code IS NOT NULL 
SELECT @v_latitude=z_latitude, @v_longitude=z_longitude FROM tbl_ZipCodes WHERE z_zip_code = @v_zip_code 

set @strValues = @strValues + '''' + @v_city + ''', ''' + @v_state + ''', ''' + @v_zip_code + ''', ''' + @v_daytime_phone + ''', ''' + @v_contact_name + ''', ''' 
+ @v_email_address + ''', ' + cast(@u_id as varchar) + ', ' + cast(@d_id as varchar) + ', 1, ''' + cast(CURRENT_TIMESTAMP as varchar) + ''', 1 , ''' + cast(@v_latitude as float) + ''', ''' + cast(@v_longitude as float) + ''', ''' 
+ cast(CURRENT_TIMESTAMP as varchar) + ''', dft.df_t_id, (SELECT CASE WHEN dft.df_t_v_price <> 0 THEN dft.df_t_v_price WHEN dft.df_t_v_internet_price <> 0 THEN dft.df_t_v_internet_price WHEN dft.df_t_v_other_price <> 0 THEN dft.df_t_v_other_price ELSE 0 END AS v_search_price)' 

Часть кода, который использует @v_latitude и @ v_longitude переменные здесь:

... , ''' + cast(@v_latitude as float) + ''', ''' + cast(@v_longitude as float) + ''', ... 

Игнорируйте «...», как я показываю, есть дополнительный код, который окружает эти значения.

Любая помощь будет оценена!

Edit: Вот дополнительный код, я использую:

-- Check For User Profile -- 
SELECT @counter = COUNT(*) FROM tbl_Customers WHERE u_id = @u_id 
if @counter > 0 
    SELECT @v_city=c_city, @v_state =c_state, @v_zip_code=c_zip_code,@v_daytime_phone =c_phone_number FROM tbl_Customers WHERE u_id = @u_id 
else 
    SELECT @v_city=d_city, @v_state =d_state, @v_zip_code=d_zip_code,@v_daytime_phone =d_phone_number FROM tbl_Dealers WHERE d_id = @d_id 

-- Grab Contact Information -- 
SELECT @v_contact_name = u_name, @v_email_address = u_email_address FROM tbl_Users WHERE u_id = @u_id 


-- Grab Latitude & Longitude -- 
if @v_zip_code IS NOT NULL 
    SELECT @v_latitude=z_latitude, @v_longitude=z_longitude FROM tbl_ZipCodes WHERE z_zip_code = @v_zip_code 


-- Add Additional Fields -- 
set @strFields = @strFields + 'v_city, v_state, v_zip_code, v_daytime_phone, v_contact_name, v_email_address, u_id, d_id, v_processed, v_processed_date, v_active, ,v_latitude, v_longitude, v_last_activity, v_dealerfeed, v_search_price' 
set @strJoin = @strJoin + ' LEFT JOIN tbl_Vehicles v ON v.v_stock_number = dft.df_t_v_stock_number' 
set @strValues = @strValues + '''' + @v_city + ''', ''' + @v_state + ''', ''' + @v_zip_code + ''', ''' + @v_daytime_phone + ''', ''' + @v_contact_name + ''', ''' 
+ @v_email_address + ''', ' + cast(@u_id as varchar) + ', ' + cast(@d_id as varchar) + ', 1, ''' + cast(CURRENT_TIMESTAMP as varchar) + ''', 1 , ''' + @v_latitude + ''', ''' + @v_longitude + ''', ''' 
+ cast(CURRENT_TIMESTAMP as varchar) + ''', dft.df_t_id, (SELECT CASE WHEN dft.df_t_v_price <> 0 THEN dft.df_t_v_price WHEN dft.df_t_v_internet_price <> 0 THEN dft.df_t_v_internet_price WHEN dft.df_t_v_other_price <> 0 THEN dft.df_t_v_other_price ELSE 0 END AS v_search_price)' 

-- Insert Records Into Vehicle Table (but not twice!) -- 
set @strSQL = 'INSERT INTO tbl_Vehicles (' + @strFields + ') SELECT ' + @strValues + ' FROM tbl_DealerFeed_temp dft ' + @strJoin + ' WHERE dft.df_t_processed = 0 AND dft.df_d_id = ' + cast(@df_d_id as varchar) 
set @strSQL = @strSQL + ' AND dft.df_t_v_stock_number NOT IN (SELECT v.v_stock_number FROM tbl_Vehicles v WHERE v.d_id = ' + cast(@d_id as varchar) + ')' 

print @strSQL 

EXEC (@strSQL) 
+1

Если это уже поплавок, и вы пытаетесь объединить его в строку, вам нужно Конвери float to (n) varchar – Jeremy

+0

@Jeremy - Я не уверен, что понимаю, что вы говорите. Я понимаю, что он уже объявлен как плавающий. Когда я пытаюсь сделать следующее, я получаю ту же ошибку, что и изначально: '- '' '+ @v_latitude +' '', '' '+ @v_longitude +' ''' – Brandon

+0

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

ответ

2

Проблема, вероятно, в том, что ваш динамический sql ставит одинарные кавычки вокруг float.

Попробуйте изменить

, ''' + cast(@v_latitude as float) + ''', ''' + cast(@v_longitude as float) + ''', .. 

в

, ' + STR(@v_latitude,<length>,<decimals>) + ', ' + STR(@v_longitude,<length>,<decimals>) + ', .. 

См STR() для справки

+0

Том, в настоящее время мой код отключает десятичные знаки. Я использую приведенный ниже код 'CONVERT (varchar (20), @v_latitude)'. Будет ли ваш код устранять эту проблему? – Brandon

+0

Нет, у меня было окно ответа на какое-то время, и Хьюго набрал его ответ, пока меня не было. Сначала я должен был обновить страницу. Наш код делает примерно то же самое. Я обновлю свой ответ –

+0

Отлично работает. Спасибо, Том! – Brandon

0

вы можете попробовать

''' + cast(@v_latitude as varchar(20)) 
+ ''', ''' + cast((@v_longitude as varchar(20))+ ''' 
+0

это уже поплавок, зачем бросать его плавать? – Jeremy

+0

@Benjamin - это дало мне ошибку SQL ... – Brandon

+0

Переменные могут быть либо поплавком, либо строкой. Если вы хотите сохранить его в столбце типа float, вы хотите, чтобы он имел тип float, если вы хотите, чтобы он был частью строки, он должен быть строкой (char или nchar) или отличать ее, чтобы стать строкой. –

1

Как вы делаете динамический SQL вы принуждать все, вплоть до строкового типа.

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

Также я нахожу CONVERT немного более гибкий (с датами в основном), чем CAST (я только сделал CONVERT для разнообразия):

так что вы хотите избавиться от этих тройных кавычек:

...+ CONVERT(varchar(20), @v_latitude) +',' + CONVERT(varchar(20), @v_longitude) +...

Edited добавить: ваш фиксированный код должен выглядеть следующим образом:

set @strValues = @strValues + '''' + @v_city + ''', ''' + @v_state + ''', ''' + @v_zip_code + ''', ''' + @v_daytime_phone + ''', ''' + @v_contact_name + ''', ''' 
+ @v_email_address + ''', ' + cast(@u_id as varchar) + ', ' + cast(@d_id as varchar) + ', 1, ''' + cast(CURRENT_TIMESTAMP as varchar) + ''', 1 , ' + Convert(varchar(20), @v_latitude) + ', ' + Convert(varchar(20), @v_longitude) + ', ''' 
+ cast(CURRENT_TIMESTAMP as varchar) + ''', dft.df_t_id, (SELECT CASE WHEN dft.df_t_v_price <> 0 THEN dft.df_t_v_price WHEN dft.df_t_v_internet_price <> 0 THEN dft.df_t_v_internet_price WHEN dft.df_t_v_other_price <> 0 THEN dft.df_t_v_other_price ELSE 0 END AS v_search_price)' 

Выполнить ваш SQL безEXEC (@strSQL) и посмотреть на отпечатанной SQL

Отредактировано снова; для фиксации вашего Float ограничено округлением до 4 знаков после запятой (это зависит от того, является ли это Float), но вы можете обойти его, преобразовывая его в десятичную строку или используя STR, это поможет вам понять, что происходит:

declare @v_latitude float = -45.12345678 
print @v_latitude 
print 'Cast = '+ cast(@v_latitude as varchar) 
print 'Convert = '+ convert(varchar(20), @v_latitude) 
print 'Cast via decimal = '+ cast(cast(@v_latitude as decimal(18,9)) as varchar) 
print 'Convert via decimal = '+ convert(varchar(20), convert(decimal(18,9), @v_latitude)) 
print 'str = '+ str(@v_latitude,18,9) 

== 
-45.1235 
Cast = -45.1235 
Convert = -45.1235 
Cast via decimal = -45.123456780 
Convert via decimal = -45.123456780 
str = -45.123456780 
+0

Я получил следующую ошибку: Microsoft OLE DB Provider для ошибки SQL Server «80040e14» – Brandon

+0

Это что? Не удается вставить ошибку «null»? –

+0

Казалось, это трюк. Тем не менее, он отсекает часть десятичного значения. Например, значение 45.751671 вводится в БД как 45.7517. Мне просто нужно увеличить размер varchar (20)? – Brandon