奇怪的问题!

FrameSniper 2008-10-17 01:12:53
create procedure udsp_SelectTruckType
@Name nvarchar(16),
@StandardLoadAmount real
as
if datalength(rtrim(ltrim(@Name)))=0
set @Name=null
if datalength(rtrim(ltrim(@StandardLoadAmount)))=0
set @StandardLoadAmount=null
declare @SelectStatement nvarchar(4000)
set @SelectStatement='select ttf_Index 流水号,
ttf_Name 名称,
ttf_StandardLoadAmount 标重
from udfdt_TruckType where ttf_Name='+isnull('''' + @Name + '''','ttf_Name')+
' and ttf_StandardLoadAmount='+isnull(convert(nvarchar(22),@StandardLoadAmount),'ttf_StandardLoadAmount')
execute(@SelectStatement)

go

这个存储过程,在表中有记录的情况下,使用
exec udsp_TruckType ' ',' ' 查不出任何东西?
...全文
126 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
pt1314917 2008-10-17
  • 打赏
  • 举报
回复
...
FrameSniper 2008-10-17
  • 打赏
  • 举报
回复
to pt1314917

公司代码要统一风格。没办法

to szx1999

我刚才把我的存储过程改写了一下,如下

create procedure udsp_SelectTruckType
@Name nvarchar(16),
@StandardLoadAmount real
as
if datalength(rtrim(ltrim(@Name)))=0
set @Name=null
if isnumeric(@StandardLoadAmount)=0
set @StandardLoadAmount=null
declare @SelectStatement nvarchar(4000)
set @SelectStatement='select ttf_Index 流水号,
ttf_Name 名称,
ttf_StandardLoadAmount 标重
from udfdt_TruckType where ttf_Name='+isnull('''' + @Name + '''','ttf_Name')+
' and ttf_StandardLoadAmount='+convert(nvarchar(22),isnull(@StandardLoadAmount,'ttf_StandardLoadAmount'))

--execute(@SelectStatement)
print @selectstatement
if len(isnull(@StandardLoadAmount,'ttf_StandardLoadAmount'))=22
raiserror('is zero',16,1)
else
raiserror('is not zero',16,1)


go


exec udsp_selecttrucktype ' ',' '

当使用isnumeric判断real类型参数是否为一个数字后,当不为数字的时候直接设置real类型参数值为null

最后在where子句中convert(nvarchar(22),isnull(@StandardLoadAmount,'ttf_StandardLoadAmount')),但结果还是0

就我理解,首先是isnull执行,判断@Standardloadamount为null后默认值就成了字串ttf_standardloadamount,然后convert直接转换全字符串形成恒等式了

可最后print后convert结果还是0
等不到来世 2008-10-17
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 FrameSniper 的回复:]
这个我明白了,不过感觉很奇怪,我的参数申明的是real类型,然后我给参数传递一个空格字串
使用了datalength(rtrim(ltrim(@param)))之后,这个串的长度为什么还是是1
rtrim和ltrim不是把空格都去掉了吗,为什么datalength计算出来还是1
而且convert以后值变成了0?能
[/Quote]
将一个' '赋给real型变量时,系统会隐式转换为0.
你用ltrim把这个数字0又变成字符串'0',所以再用datalength自然就是1了。

实际上你把任意长的空串赋给real变量,最后结果都是0:
declare @StandardLoadAmount real
set @StandardLoadAmount = ' '
select @StandardLoadAmount
pt1314917 2008-10-17
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 FrameSniper 的回复:]
to 小雄

你的那三句话说明了什么,能告诉我一下吗?
[/Quote]

自己对照这种形式去写。很简单的。

create procedure udsp_SelectTruckType
@Name nvarchar(16)=null,
@StandardLoadAmount real=null
as
declare @where varchar(100)
set @where =''
if @Name is not null
set @where=@where+' and ttf_Name='''+@Name+''''
if @StandardLoadAmount is not null
set @where=@where+' and ttf_StandardLoadAmount='+ltrim(@StandardLoadAmount)

declare @SelectStatement nvarchar(4000)
set @SelectStatement='select ttf_Index 流水号,ttf_Name 名称,ttf_StandardLoadAmount 标重 from udfdt_TruckType where 1=1'+@where
execute(@SelectStatement)
go


--调用
exec udsp_SelectTruckType null,43
exec udsp_SelectTruckType '34',null
等等。

FrameSniper 2008-10-17
  • 打赏
  • 举报
回复
这个我明白了,不过感觉很奇怪,我的参数申明的是real类型,然后我给参数传递一个空格字串
使用了datalength(rtrim(ltrim(@param)))之后,这个串的长度为什么还是是1
rtrim和ltrim不是把空格都去掉了吗,为什么datalength计算出来还是1
而且convert以后值变成了0?能
等不到来世 2008-10-17
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 FrameSniper 的回复:]
to 小雄

你的那三句话说明了什么,能告诉我一下吗?
[/Quote]
是想说明你用datalength(ltrim(trim...的方式是无效的。

另外再给你几个示例做参考:
declare @StandardLoadAmount real
set @StandardLoadAmount = ' '
select isnumeric(@StandardLoadAmount) -- return 1
select isnumeric(' ') -- return 0


等不到来世 2008-10-17
  • 打赏
  • 举报
回复
所以根本没走这条路:
if datalength(rtrim(ltrim(@SuperiorDeptName)))=0
set @SuperiorDeptIndex=null

于是@SuperiorDeptIndex一直等于' ',
convert(nvarchar(20),@SuperiorDeptIndex)就一直=0
FrameSniper 2008-10-17
  • 打赏
  • 举报
回复
to 小雄

你的那三句话说明了什么,能告诉我一下吗?
等不到来世 2008-10-17
  • 打赏
  • 举报
回复
空串转化成数字就变成0了,再datalength就自然得到1了。
FrameSniper 2008-10-17
  • 打赏
  • 举报
回复
柱子,先问你个问题

我还有另外一个貌似这样的存储过程,执行后可以查出来

create procedure udsp_SelectDepartment
@Name nvarchar(16),
@SuperiorDeptName nvarchar(16)
as
if datalength(rtrim(ltrim(@Name)))=0
set @Name=null
declare @SuperiorDeptIndex smallint
if datalength(rtrim(ltrim(@SuperiorDeptName)))=0
set @SuperiorDeptIndex=null
else
set @SuperiorDeptIndex=isnull((select df_Index from udfdt_Department where df_Name=@SuperiorDeptName),0)
declare @SelectStatement nvarchar(4000)
set @SelectStatement='select df_Index 流水号,
df_Name 名称,
(select df_Name from udfdt_Department where df_Index=a.df_SuperiorDeptIndex) 上级部门
from udfdt_Department a where df_Name='+isnull('''' + @Name + '''','df_name')+
' and df_SuperiorDeptIndex='+isnull(convert(nvarchar(20),@SuperiorDeptIndex),'df_SuperiorDeptIndex')
execute(@SelectStatement)


go


另外,我不太明白为什么isnull(convert(nvarchar(22),@StandardLoadAmount),'ttf_StandardLoadAmount')这个最后的结果是0

@standardloadamount我传递进存储过程的时候是个空格,经过datalength(rtrim(ltrim()))处理后就成了空字符了
在使用isnull进行判断的时候,先使用convert应该转换出来也是空,所以最后想的是取ttf_standardloadamount,但好像结果却不是这样
等不到来世 2008-10-17
  • 打赏
  • 举报
回复
declare @StandardLoadAmount real
set @StandardLoadAmount = ' '
select datalength(rtrim(ltrim(@StandardLoadAmount)))
/*
---
1
*/
pt1314917 2008-10-17
  • 打赏
  • 举报
回复

--改成这样:
create procedure udsp_SelectTruckType
@Name nvarchar(16),
@StandardLoadAmount real
as
declare @where varchar(100)
set @where =''
if datalength(rtrim(ltrim(@Name)))!=0
set @where=@where+' and ttf_Name='''+@Name+''''
if datalength(rtrim(ltrim(@StandardLoadAmount)))!=0
set @where=@where+' and ttf_StandardLoadAmount='+ltrim(@StandardLoadAmount)

declare @SelectStatement nvarchar(4000)
set @SelectStatement='select ttf_Index 流水号,
ttf_Name 名称,
ttf_StandardLoadAmount 标重
from udfdt_TruckType where 1=1'+@where
execute(@SelectStatement)
go
FrameSniper 2008-10-17
  • 打赏
  • 举报
回复
to qianjin036a

您的这个打印出来如下


select ttf_Index 流水号,
ttf_Name 名称,
ttf_StandardLoadAmount 标重
from udfdt_TruckType where ttf_Name='ttf_Name' and ttf_StandardLoadAmount=0

好像还是不对
-晴天 2008-10-17
  • 打赏
  • 举报
回复
set @SelectStatement='select ttf_Index 流水号, 
ttf_Name 名称,
ttf_StandardLoadAmount 标重
from udfdt_TruckType where ttf_Name='''+isnull(@Name,'ttf_Name')+
''' and ttf_StandardLoadAmount='+isnull(convert(nvarchar(22),@StandardLoadAmount),'ttf_StandardLoadAmount')
FrameSniper 2008-10-17
  • 打赏
  • 举报
回复
如果用动态SQL形式,在我这个基础上怎么改呢?
等不到来世 2008-10-17
  • 打赏
  • 举报
回复
其实不需要动态sql.
alter procedure udsp_SelectTruckType 
@Name nvarchar(16),
@StandardLoadAmount real
as
if datalength(rtrim(ltrim(@Name)))=0
set @Name=null
if datalength(rtrim(ltrim(@StandardLoadAmount)))=0
set @StandardLoadAmount=null
select ttf_Index 流水号,
ttf_Name 名称,
ttf_StandardLoadAmount 标重
from udfdt_TruckType where ttf_Name=isnull(@Name,ttf_Name)
and ttf_StandardLoadAmount=isnull(@StandardLoadAmount,ttf_StandardLoadAmount)
go
等不到来世 2008-10-17
  • 打赏
  • 举报
回复
print出来你会发现总是这句:
select ttf_Index 流水号, 
ttf_Name 名称,
ttf_StandardLoadAmount 标重
from udfdt_TruckType where ttf_Name=ttf_Name and ttf_StandardLoadAmount=0

所以查不出来。

hyde100 2008-10-17
  • 打赏
  • 举报
回复
先调试sql手动赋值看看有没有问题
pt1314917 2008-10-17
  • 打赏
  • 举报
回复
貌似楼主调用时,存储过程名字都写错了吧?
exec udsp_TruckType ' ',' '
东那个升 2008-10-17
  • 打赏
  • 举报
回复
自己print 一下!看看语句有问题没有!

34,593

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧