Why is variable declared inside IF statement created even when condition evaluates to false?
SQL Server does not have block level variable scoping.
It's per batch/stored proc etc
From MSDN (my bold)
The scope of a variable is the range
of Transact-SQL statements that can
reference the variable. The scope of a
variable lasts from the point it is
declared until the end of the batch or
stored procedure in which it is
declared.
why sometime variable are used as condition in if statement in javascript?
Here variable can be a boolean value or sometime to check variable existence you check it in if statement. Condition you might test with if statement.
- Element exist or not
- Input value empty or not
- collection length zero or greater
So following code:
if(result){
//do something
}
will cause false in the following condition(also called falsy):
- false
- 0 (zero)
- "" (empty string)
- null
- undefined
- NaN (a special Number value meaning Not-a-Number!)
Why can't we define a variable inside an if statement?
This is because section 8.5.1 of the C# language spec. states:
Furthermore, a variable initializer in a local variable declaration corresponds exactly to an assignment statement that is inserted immediately after the declaration.
This basically means that, when you do:
StringBuilder sb = new StringBuilder("test")
You're, in effect, doing the exact same thing as:
StringBuilder sb; sb = new StringBuilder("test")
As such, there is no longer a return value for your check against != null
, as the assignment isn't a single expression, but rather a statement, which is a local-variable-declarator comprised of an identifier followed by an expression.
The language specification gives this example, stating that this:
void F() {
int x = 1, y, z = x * 2;
}
Is exactly equivalent to:
void F() {
int x; x = 1;
int y;
int z; z = x * 2;
}
C++, variable declaration in 'if' expression
As of C++17 what you were trying to do is finally possible:
if (int a = Func1(), b = Func2(); a && b)
{
// Do stuff with a and b.
}
Note the use of ;
of instead of ,
to separate the declaration and the actual condition.
Why does non-equality check of one variable against many values always return true?
Use &&
/AND
/and
, not ||
/OR
/or
:
v != "x" && v != "y" && v != "z"
Problem
If an if
block is always executed, the condition for the if block always evaluates to true
. The logical expression must be wrong.
Let us consider v != "x" || v != "y" || v != "z"
for each value of v
.
When
v = "x"
,v != "x"
becomes"x" != "x"
, which is false.v != "y"
becomes"x" != "y"
, which is true.v != "z"
becomes"x" != "z"
, which is true.The expression evaluates to
false || true || true
, which is true.When
v = "y"
, the expression becomes"y" != "x" || "y" != "y" || "y" != "z"
or
true || false || true
, which is true.When
v = "z"
, the expression becomes"z" != "x" || "z" != "y" || "z" != "z"
or
true || true || false
, which is true.For any other value for
v
, the expression evaluates totrue || true || true
, which is true.
Alternatively, consider the truth-table:
│ A B C │
v │ v != "x" v != "y" v != "z" │ A || B || C
───────┼──────────────────────────────────┼──────────────
"x" │ false true true │ true
"y" │ true false true │ true
"z" │ true true false │ true
other │ true true true │ true
As you can see, your logical expression always evaluates to true
.
Solution
What you want to do is, find a logical expression that evaluates to true
when
(v is not "x")
and
(v is not "y")
and
(v is not "z")
.
The correct construction is,
for C-like languages (eg. c#, javascript-(may need the strict equality operator
!==
), php)if (v != "x" && v != "y" && v != "z")
{
// the statements I want to be executed
// if v is neither "x", nor "y", nor "z"
}for Pascal-like languages plsql
IF (v != 'x' AND v != 'y' AND v != 'z') THEN
-- the statements I want to be executed
-- if v is neither "x", nor "y", nor "z"
END IF;
De Morgan's law
By De Morgan's law, the expression can also be rewritten as (using C-like syntax)
!(v == "x" || v == "y" || v == "z")
meaning
not
((v is "x")
or
(v is "y")
or
(v is "z"))
.
This makes the logic a bit more obvious.
Specific languages
Some languages have specific constructs for testing membership in sets, or you can use array/list operations.
sql:
v NOT IN ('x', 'y', 'z')
javascript:
["x", "y", "z"].indexOf(v) == -1
python:
v not in {"x", "y", "z"}
java:
!Arrays.asList("x", "y", "z").contains(v)
java-9 (and above):
!Set.of("x", "y", "z").contains(v)
R: IF statement evaluating expression despite condition being FALSE?
Solution
Adapting your example use:
testfun <- function(x,grids = NULL)
{
if(!is.null(grids)){
if(!all(expvarnames %in% names(grids))){
stop("Not all expvar column names found as column names in grids")
}
print(x+1)
}
}
Using this testfun(1)
will return nothing. By specifying a default argument in the function as NULL
the function then checks for this (i.e. no argument specified) and then doesn't continue the function if so.
The Reason the Problem Occurs
We go through each of the examples:
testfun <- function(x,grids)
{if(exists("grids")) globalgrids<<-grids
print(x+1)}
testfun(1) # Error in testfun(1) : argument "grids" is missing, with no default
Here we call the function testfun
, giving only the x
argument. testfun
knows it needs two arguments, and so creates local variables x
and grids
. We have then given an argument to x
and so it assigns the value to x
. There is no argument to grids
, however the variable has still been created, even though no value has been assigned to it. So grids
exists, but has no value.
From this exists("grids")
will be TRUE
, but when we try to do globalgrids<<-grids
we will get an error as grids
has not been assigned a value, and so we can't assign anything to globalgrids
.
testfun <- function(x,grids)
{if(exists("grids")) a<<-c(1,2,3)
print(x+1)}
testfun(1) #2 (and globally assigns a)
This, however is fine. grids
exists as in the previous case, and we never actually try and access the value stored in grids
, which would cause an error as we have not assigned one.
In the solution, we simply set a default value for grids
, which means we can always get something whenever we try and access the variable. Unlike in the previous cases, we will get NULL
, not that nothing is stored there.
The main point of this is that when you declare arguments in your function, they are created each time you use the function. They exist. However, if you don't assign them values in your function call then they will exist, but have no value. Then when you try and use them, their lack of values will throw an error.
Why can't variables be declared in an if statement?
Why? There can be no code path leading to the program assigning 1 to b without declaring it first.
You are right, but the compiler doesn't know that. The compiler does not execute the code. The compiler only translates to bytecode without evaluating expressions.
IF statement not raising error as expected
You need to declare your variable with a type before you can use it
declare @xyz int -- assuming the datatype of column riskgroup is also int
select @xyz = riskgroup
from polcont
where polcont = 555
EDIT
You altered your question since I have posted my answer, now your problem is you declare the variable in the wrong scope.
DECLARE @XYZ int
if @Ref = 0
begin
SELECT @XYZ = RISKGROUP
FROM POLCONT --WITH (NOLOCK, NOWAIT) don't do nolock everywhere !
WHERE CONT = 555
end
if @RISKGROUP <> @XYZ
begin
-- do something ...
end
EDIT 2
As to your question why it does not give any error, that is strange indeed
See this DBFiddle
I would indeed expect an error, but it somehow does not
This is explained in the documents as normal per design, though in my mind it is a flaw.
Also see this Question about the same subject
EDIT 3
So it seems that is does not matter much in TSQL where you declare your variables, but as a programmer I find this looking weird, so I prefer to put my variables in what is for me the correct scope.
Related Topics
Logging Erroneous Queries Only on SQL Server
Help with Writing a SQL Query for Nested Sets
How to Insert into Two Tables All at Once in a Stored Procedure
Snowflake: "SQL Compilation Error:... Is Not a Valid Group by Expression"
Find Start and Stop Date for Contiguous Dates in Multiple Rows
Tree Structure in SQL in Oracle.How to Show Tree,Child Nodes and Parent Nodes in SQL Oracle
Bigquery: How to Group and Count Rows Within Rolling Timestamp Window
Using with Nolock Table Hint in Query Using View - Does It Propagate Within the View
Change Datatype Varchar to Nvarchar in Existing SQL Server 2005 Database. Any Issues
How to Find SQL Language Specification
Can SQL Profiler Display Return Result Sets Alongside the Query
Generate SQL Temp Table of Sequential Dates to Left Outer Join To
Group or Distinct After Join Returns Duplicates
"Ambiguous Column Name" Error on One Particular Server
ASP.NET MVC: Execute Razor from Db String